1. Strong parameters and mass assignment
Rails strong parameters require controllers to explicitly whitelist attributes before they reach ActiveRecord. The bypass patterns we test for are: using .permit! which whitelists all attributes unconditionally, nesting permitted attributes in a way that allows unexpected keys through the nested hash, and controller actions that construct attributes from request data without going through params.require().permit() at all:
# VULNERABLE: .permit! whitelists every attribute including internal columns
def user_params
params.require(:user).permit!
end
# Attacker submits: { "user": { "role": "admin", "verified": true } } 2. Ruby deserialization and Marshal gadget chains
Rails uses cookies signed with the application secret key. Older Rails applications (pre-7.0) using the default Marshal cookie serializer are vulnerable to Remote Code Execution if the secret_key_base is compromised. An attacker who knows the secret key can craft a cookie containing a serialized Ruby object that executes shell commands when the server deserializes the cookie. We check your cookie serializer configuration and verify that JSON serialization (not Marshal) is used for all session data.
3. Action Cable WebSocket channel authorization
Action Cable channels must validate subscriptions against the current user's identity. The most common finding is a channel that broadcasts to a stream derived from a client-supplied parameter without verifying ownership:
# VULNERABLE: stream name comes from client parameter without ownership check
class AccountChannel < ApplicationCable::Channel
def subscribed
# The caller can subscribe to an account_id they do not own
stream_from "account_{params[:account_id]}"
end
end 4. Active Storage file upload and URL manipulation
Rails Active Storage generates signed URLs for uploaded files. We test whether your storage configuration restricts access to private blobs (which should require authentication to generate a signed URL), whether the signed URL expiry is short enough to prevent link sharing, and whether your file upload validation (content type, file size, virus scanning) can be bypassed by manipulating the multipart upload request.
5. Devise authentication configuration
Most Rails applications use Devise for user authentication. We audit your Devise configuration for: password reset token entropy (is the reset token long enough to prevent brute force?), email enumeration through timing differences in the password reset response, lockout configuration (does the account lock after failed login attempts?), and session invalidation on password change (are existing sessions revoked when the password is reset?).
Action Cable subscription bypass leaking real-time financial data
An Action Cable channel builds its stream name from a client-supplied account_id. A signed-in user can subscribe to another account’s updates. Derive the stream from current_user or verify ownership before calling stream_for.
Running a Rails application handling real user data? Schedule a practitioner-led security assessment.
Book a Rails PentestFrequently asked questions
What is a strong params bypass in Ruby on Rails?
Strong parameters require developers to explicitly permit each attribute before it is used in a mass assignment operation. A bypass occurs when a developer uses .permit! (permits all) or when nested attributes are permitted without restricting the specific keys inside the nested hash.
How dangerous is Ruby deserialization?
Ruby's Marshal.load deserializes arbitrary Ruby objects. If user-controlled data reaches a Marshal.load call, an attacker can craft a payload using a known Ruby gadget chain to execute arbitrary system commands (Remote Code Execution). This is one of the most critical vulnerability classes in Rails applications.
What is the security risk of Rails Action Cable?
Action Cable provides WebSocket-based real-time features. Each channel's connection and subscription methods must validate the current user's authorization. If a channel broadcasts data to a stream without validating that the subscriber owns that stream, any authenticated user can subscribe to any other user's private data stream.
Related reading
Blog: Django penetration testing · Laravel penetration testing · BOLA in payment APIs
Services: Penetration testing · API security testing