GuardAPI Logo
GuardAPI

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_token

def 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_token

def 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

System Alert • ID: 7754
Target: Rails API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.