Fix Insecure Webhooks in Pyramid
Webhooks are frequently the weakest link in an API's security posture. In Pyramid, exposing a POST endpoint that processes payloads without cryptographic verification is an open invitation for SSRF, data injection, or unauthorized command execution. To secure these, you must implement HMAC-SHA256 signature verification to ensure the request body originated from a trusted provider and remained untampered in transit.
The Vulnerable Pattern
from pyramid.view import view_config
@view_config(route_name=‘webhook_receiver’, renderer=‘json’, request_method=‘POST’) def insecure_webhook(request): # VULNERABILITY: Blindly trusting the incoming JSON payload # An attacker can forge this request to trigger internal logic. data = request.json_body process_order(data[‘order_id’]) return {‘status’: ‘processed’}
The Secure Implementation
The secure implementation introduces three critical defenses. First, it uses the raw `request.body` for HMAC calculation; using parsed JSON can lead to discrepancies if the parser normalizes keys or whitespace. Second, it utilizes `hmac.new` with a shared secret to verify integrity and authenticity. Finally, it employs `hmac.compare_digest` for a constant-time comparison, which is essential to prevent side-channel timing attacks that could allow an attacker to brute-force the signature character by character.
import hmac
import hashlib
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPForbidden
Securely stored secret
WEBHOOK_SECRET = b’your_high_entropy_shared_secret’
@view_config(route_name=‘webhook_receiver’, renderer=‘json’, request_method=‘POST’)
def secure_webhook(request):
# 1. Extract the signature header
header_signature = request.headers.get(‘X-Hub-Signature-256’)
if not header_signature:
raise HTTPForbidden(‘Missing Signature’)
# 2. Compute the HMAC using the raw request body
# Use the shared secret and SHA256
expected_signature = hmac.new(
WEBHOOK_SECRET,
request.body,
hashlib.sha256
).hexdigest()
# 3. Constant-time comparison to prevent timing attacks
if not hmac.compare_digest(expected_signature, header_signature):
raise HTTPForbidden('Invalid Signature')
# 4. Only process once identity is verified
data = request.json_body
process_order(data['order_id'])
return {'status': 'verified_and_processed'}</code></pre>
Your Pyramid API
might be exposed to Insecure Webhooks
74% of Pyramid 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.