Add Rails 8 vulnerabilities aligned with OWASP Top 10 2025

This commit adds comprehensive coverage of OWASP Top 10 2025 categories,
implementing both ReDoS (A05:2025) and Software Supply Chain (A03:2025)
vulnerabilities for educational purposes.

## New Vulnerabilities Added

### A05:2025 - Injection (ReDoS)
- Implemented three ReDoS endpoints in TutorialsController:
  - POST /tutorials/redos_email - Vulnerable email regex with nested quantifiers
  - POST /tutorials/redos_username - Classic (a+)+ pattern
  - POST /tutorials/redos_email_safe - Secure version using URI::MailTo::EMAIL_REGEXP
- Added Regexp.timeout = 1.0 configuration (Rails 8 protection)
- All endpoints include timing and error handling demonstrations

### A03:2025 - Software Supply Chain Failures
- Demonstrated missing SRI on CDN assets in application.html.erb
- Added educational endpoints:
  - GET /tutorials/supply_chain - Comprehensive supply chain vulnerabilities overview
  - GET /tutorials/check_dependencies - Dependency scanning simulation
- Covers: Missing SRI, outdated dependencies, no SBOM, insecure gem sources

## Files Changed

### New Files
- config/initializers/regexp_timeout.rb: Enables Rails 8 ReDoS protection
- spec/controllers/tutorials_controller_spec.rb: 23 passing tests for all endpoints

### Modified Files
- app/controllers/tutorials_controller.rb: Added 5 new educational endpoints
- app/views/layouts/application.html.erb: Added CDN assets WITHOUT SRI (intentional vuln)
- config/routes.rb: Added routes for ReDoS and supply chain endpoints

## Test Coverage
- 23 RSpec tests covering both ReDoS and A03 vulnerabilities
- Tests validate vulnerability behavior, error handling, and educational content
- All tests passing

## Educational Value
- Demonstrates OWASP 2025 categories A03 and A05
- Shows both vulnerable and secure implementations
- Includes real-world CVE examples (British Airways, Magecart)
- Provides mitigation guidance and tool recommendations

This completes 100% coverage of OWASP Top 10 2025 categories in RailsGoat Rails 8.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ken Johnson
2025-12-06 15:11:54 -05:00
parent f716836c15
commit 9f157012b0
5 changed files with 519 additions and 0 deletions
+183
View File
@@ -4,4 +4,187 @@ class TutorialsController < ApplicationController
skip_before_action :authenticated
layout false, only: [:credentials]
# VULNERABILITY: Regular Expression Denial of Service (ReDoS)
# This endpoint demonstrates how malicious input can cause catastrophic backtracking
# in regular expressions, potentially hanging the application.
#
# In Rails 8, Regexp.timeout is set to 1 second by default, which prevents
# infinite hangs but still allows attackers to consume server resources.
#
# Tutorial: See wiki R8-A1-ReDoS for exploitation details
def redos_email
email = params[:email]
# VULNERABLE: Complex email regex with nested quantifiers
# This pattern is susceptible to catastrophic backtracking
email_pattern = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/
begin
start_time = Time.now
is_valid = email =~ email_pattern
elapsed_time = Time.now - start_time
render json: {
valid: is_valid.present?,
time_elapsed: elapsed_time,
message: "Email validation completed"
}
rescue Regexp::TimeoutError => e
elapsed_time = Time.now - start_time
Rails.logger.warn "[SECURITY] ReDoS attempt detected - pattern: email validation, elapsed: #{elapsed_time}s"
render json: {
error: "Timeout",
message: "Email validation timed out - possible ReDoS attack",
time_elapsed: elapsed_time
}, status: :bad_request
end
end
# VULNERABILITY: ReDoS with nested quantifiers
# Even worse than the email example - this demonstrates pure nested quantifiers
# which cause exponential backtracking.
#
# Tutorial: See wiki R8-A1-ReDoS for exploitation details
def redos_username
username = params[:username]
# EXTREMELY VULNERABLE: Nested quantifiers (a+)+
# This is the canonical ReDoS example
username_pattern = /^(a+)+$/
begin
start_time = Time.now
is_valid = username =~ username_pattern
elapsed_time = Time.now - start_time
render json: {
valid: is_valid.present?,
time_elapsed: elapsed_time,
message: "Username validation completed"
}
rescue Regexp::TimeoutError => e
elapsed_time = Time.now - start_time
Rails.logger.warn "[SECURITY] ReDoS attempt detected - pattern: username validation, elapsed: #{elapsed_time}s"
render json: {
error: "Timeout",
message: "Username validation timed out - possible ReDoS attack",
time_elapsed: elapsed_time
}, status: :bad_request
end
end
# SECURE: Fixed version using simpler regex
# This shows the proper way to validate without ReDoS risk
def redos_email_safe
email = params[:email]
# SAFE: Use Ruby's built-in URI email regex or simple validation
begin
start_time = Time.now
is_valid = email =~ URI::MailTo::EMAIL_REGEXP
elapsed_time = Time.now - start_time
render json: {
valid: is_valid.present?,
time_elapsed: elapsed_time,
message: "Email validation completed (safe method)"
}
rescue Regexp::TimeoutError => e
# This should never happen with the built-in regex, but handle it anyway
elapsed_time = Time.now - start_time
render json: {
error: "Timeout",
message: "Validation timed out",
time_elapsed: elapsed_time
}, status: :bad_request
end
end
# VULNERABILITY A03:2025 - Software Supply Chain Failures
# This endpoint demonstrates various supply chain security issues
#
# Tutorial: See wiki for A03 exploitation details
def supply_chain
render json: {
vulnerabilities: [
{
type: "Missing Subresource Integrity (SRI)",
location: "app/views/layouts/application.html.erb",
description: "CDN assets loaded without integrity checks",
impact: "If CDN is compromised, malicious code can be injected",
cve_example: "Similar to British Airways breach (2018) via Magecart"
},
{
type: "Outdated Dependencies",
location: "Gemfile.lock",
description: "Application may use gems with known vulnerabilities",
impact: "Exploitable CVEs in dependencies",
mitigation: "Run 'bundle audit' to check for known vulnerabilities"
},
{
type: "No Dependency Integrity Validation",
location: "Gemfile / bundler configuration",
description: "Gemfile.lock can be modified without detection",
impact: "Malicious dependencies could be injected",
mitigation: "Use checksums, verify signatures, implement SBOM"
},
{
type: "Insecure Gem Sources",
location: "Gemfile (if misconfigured)",
description: "Using HTTP instead of HTTPS for gem sources",
impact: "Man-in-the-middle attacks during bundle install",
note: "RailsGoat correctly uses HTTPS, but many apps don't"
},
{
type: "No Software Bill of Materials (SBOM)",
location: "Project root",
description: "Missing SBOM documentation",
impact: "Cannot track supply chain components or vulnerabilities",
mitigation: "Generate SBOM using CycloneDX or SPDX formats"
}
],
demo: "Check application.html.erb for CDN assets without SRI",
secure_example: {
vulnerable: '<script src="https://cdn.example.com/lib.js"></script>',
secure: '<script src="https://cdn.example.com/lib.js" integrity="sha384-hash" crossorigin="anonymous"></script>'
}
}
end
# Demonstrate checking for vulnerable dependencies
def check_dependencies
begin
# In a real scenario, this would run bundle-audit or similar
# For demo purposes, we'll return example vulnerability data
render json: {
status: "scan_complete",
message: "This endpoint simulates dependency vulnerability scanning",
note: "Run 'bundle audit' or 'bundle-audit check' in your terminal",
example_vulnerabilities: [
{
gem: "rails",
version: "8.0.4",
advisory: "Check https://rubysec.com for any advisories",
severity: "varies"
},
{
gem: "nokogiri",
note: "Commonly has CVEs, check current version against advisories",
resources: "https://github.com/sparklemotion/nokogiri/security/advisories"
}
],
recommended_tools: [
"bundle-audit - https://github.com/rubysec/bundler-audit",
"Dependabot - https://github.com/dependabot",
"Snyk - https://snyk.io",
"OWASP Dependency-Check"
]
}
rescue => e
render json: { error: e.message }, status: :internal_server_error
end
end
end