AI Security Summary
Ruby on Rails exposes attack surfaces across template rendering, request parsing, and ActiveRecord data handling. The recurring coding mistake is trusting user-controlled input—file paths, headers, query parameters, and SQL annotations—without strict sanitization before passing it to framework internals.
Arbitrary File Read via Template Rendering and Path Traversal
Covers: CVE-2014-0130 · CVE-2016-0752 · CVE-2019-5418 Risk: ACTIVELY EXPLOITED: Attackers use crafted request paths or Accept headers to escape the views directory and read arbitrary server files.
- NEVER pass user-supplied input directly or indirectly to render, render file:, or any method that resolves a view template path.
- ALWAYS restrict route globbing patterns so that captured segments cannot traverse outside the intended controller/action namespace.
- NEVER allow the Accept header to influence which file path is resolved during rendering without allowlist validation.
- ALWAYS treat any path component containing '..' or null bytes as malicious and reject the request before it reaches the render layer.
- NEVER render a file whose path is constructed from request parameters without first canonicalizing and confirming the resolved path is within the designated template root.
ReDoS via Unbounded Regex on User-Controlled Input
Covers: CVE-2024-26142 · CVE-2024-26143 · CVE-2024-41128 · CVE-2024-47887 · CVE-2026-33169 · CVE-2026-33176 Risk: Crafted HTTP headers, query parameters, or numeric strings trigger catastrophic backtracking in framework regexes, causing denial-of-service.
- NEVER apply regex matching with unbounded quantifiers to raw, user-supplied HTTP header values such as Authorization or Accept without length-bounding the input first.
- ALWAYS enforce a maximum length limit on query parameter strings, Accept header values, and any numeric input before they reach parsing or formatting routines.
- NEVER construct gsub or regex-based formatters that operate on strings whose length is user-controlled without bounding the input.
- ALWAYS reject or truncate inputs containing scientific notation (e.g. strings with 'e' followed by large exponents) before passing them to number formatting helpers.
- NEVER rely solely on framework-internal parsing to protect against malformed or adversarially long header or parameter payloads.
XSS via SafeBuffer Trust Bypass and DOM Injection
Covers: CVE-2023-28120 · CVE-2023-23913 · CVE-2026-33170 Risk: Unsafe mutations to html_safe-marked buffers and clipboard-based DOM injection allow attacker-controlled content to execute as trusted HTML.
- NEVER call mutating string methods (bytesplice, gsub!, %) on a SafeBuffer that has been marked html_safe and then re-insert the result into a template without re-sanitizing.
- ALWAYS re-check html_safe? status after any in-place string mutation; treat the result as untrusted until explicitly re-sanitized.
- NEVER allow contenteditable elements to accept pasted HTML that includes rails-ujs data attributes (data-method, data-remote, data-disable-with) without sanitizing clipboard content first.
- ALWAYS sanitize user-supplied content before it can reach any ERB interpolation point, even when the surrounding string originates from a trusted SafeBuffer.
Open Redirect and Header Injection via Unvalidated Redirect Targets
Covers: CVE-2023-22797 · CVE-2023-28362 · CVE-2024-28103 Risk: User-supplied redirect targets and illegal header characters enable open redirects, response-splitting risks, and missing security headers on non-HTML responses.
- NEVER pass user-controlled parameters directly to redirect_to without validating the destination against an explicit allowlist of permitted URLs or paths.
- ALWAYS strip or reject any characters that are illegal in HTTP header values before constructing a Location or any other response header from user input.
- ALWAYS ensure that security-relevant response headers, including Permissions-Policy, are applied to all Content-Types, not only text/html responses.
- NEVER infer a safe redirect target from a request parameter by URL-decoding alone; validate scheme, host, and path against application-defined constraints.
SQL Injection and Log Injection via Unsanitized Data Layer Input
Covers: CVE-2023-22794 · CVE-2022-44566 · CVE-2023-38037 · CVE-2025-55193 Risk: Unsanitized user input reaching ActiveRecord annotations, PostgreSQL adapter queries, encrypted file handling, and log output enables SQL injection, DoS, and ANSI escape injection.
- NEVER pass user-supplied strings to ActiveRecord's annotate query method or any SQL comment insertion point without exhaustive escaping for comment-breaking sequences.
- ALWAYS treat ActiveRecord find and similar lookup arguments as untrusted; ensure values are escaped before they are written to any log sink or terminal output.
- NEVER create temporary files from encrypted content using default OS permissions; explicitly set restrictive permissions before writing sensitive data.
- ALWAYS validate and bound the size and character set of any value destined for a PostgreSQL query parameter to prevent resource exhaustion in the adapter.
- NEVER log raw user-supplied IDs or identifiers without first stripping ANSI escape sequences and non-printable control characters.
Cross-cutting patterns (all Ruby on Rails projects)
- NEVER trust any value that originates from an HTTP request—headers, path segments, query parameters, or body fields—without explicit type, length, and character-set validation before it reaches Rails framework internals.
- ALWAYS apply allowlist validation rather than denylist sanitization when user input influences file paths, SQL fragments, redirect targets, or format strings.
- NEVER assume that a Rails helper or framework method provides complete input sanitization on its own; add an explicit validation layer in application code before calling the helper.
- ALWAYS enforce maximum-length constraints on all externally supplied strings at the application boundary, before any parsing, formatting, or database operation occurs.