Fix Insecure Webhooks in Rails
Webhooks are blind entry points. If you are not verifying signatures, you are essentially providing an unauthenticated API endpoint that allows attackers to manipulate your database. In Rails, the common pitfall is trusting the 'params' hash directly. A malicious actor can spoof events—like 'subscription.deleted'—to gain free services or bypass business logic. Secure implementation requires raw body HMAC verification.
The Vulnerable Pattern
class WebhooksController < ApplicationController # SECURITY RISK: CSRF protection is disabled, but no alternative auth is provided skip_before_action :verify_authenticity_tokendef receive # VULNERABLE: Direct trust of parameters from an unverified source event_type = params[:type] user = User.find_by(external_id: params[:data][:customer_id])
if event_type == 'payment.succeeded' user.upgrade_to_premium! end head :ok
end end
The Secure Implementation
The vulnerability lies in the lack of origin authentication. To fix this: 1. Use the raw request body (request.body.read) for verification, as middleware parameter parsing can alter the payload and break signature matches. 2. Retrieve the provider's signature from headers (e.g., Stripe-Signature). 3. Perform a constant-time HMAC comparison using a shared secret stored in Rails credentials. 4. Never use 'params' until the signature is validated. This prevents 'Webhook Spoofing' where an attacker mimics the provider's JSON structure to trigger unauthorized state changes.
class WebhooksController < ApplicationController skip_before_action :verify_authenticity_tokendef receive payload = request.body.read sig_header = request.env[‘HTTP_X_SIGNATURE’] endpoint_secret = Rails.application.credentials.webhook_secret
begin # SECURE: Verify HMAC signature using raw body and shared secret # This ensures the request originated from the trusted provider event = CustomWebhookProvider::Signature.verify!( payload: payload, sig_header: sig_header, secret: endpoint_secret ) rescue SignatureError => e return head :unauthorized end process_event(event) head :ok
end end
Your Rails API
might be exposed to Insecure Webhooks
74% of Rails apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.