Webhook Security
This guide covers security best practices for the endpoints that receive HTTP requests from Recuro.
Always verify signatures
If you have a signing secret configured, every outbound request from Recuro includes X-Recuro-Signature and X-Recuro-Timestamp headers. Always verify these on your server. See Webhook Authentication for implementation examples.
Skipping verification means any party that knows your endpoint URL can send fake requests.
Use HTTPS endpoints
Always use https:// URLs for your target endpoints. HTTP (without TLS) transmits request bodies — including payloads and headers — in plaintext, making them vulnerable to interception.
Recuro validates SSL certificates when making requests. If your certificate is expired or misconfigured, the request fails with an ssl_error.
Implement replay protection
The X-Recuro-Timestamp header contains the Unix timestamp when the request was signed. Reject requests where the timestamp is more than 5 minutes old:
$timestamp = (int) $request->header('X-Recuro-Timestamp');
if (abs(time() - $timestamp) > 300) { abort(403, 'Request timestamp too old');}This prevents replay attacks where an attacker captures a legitimate request and resends it later.
Rotate signing secrets periodically
Rotate your signing secret from Settings > Webhook Signing on a regular cadence:
- Deploy your updated endpoint code with the new secret first (or support both old and new secrets temporarily)
- Regenerate the secret in the dashboard
- Remove support for the old secret from your endpoint
Protect your endpoint URLs
Treat your endpoint URLs as semi-private. While webhook signing provides authentication, an attacker who knows your URL could attempt to flood it with requests. Consider:
- Using non-guessable URL paths (e.g.,
/webhooks/recuro/a3f8b2c1) - Rate limiting inbound requests on your endpoint
- Allowlisting Recuro’s IP ranges (if available)
Return proper status codes
Your endpoint should return appropriate HTTP status codes:
| Code | Meaning to Recuro |
|---|---|
200-299 | Success — execution marked as completed (subject to assertions) |
400-499 | Client error — execution marked as failed with http_client_error |
500-599 | Server error — execution marked as failed with http_server_error |
Return 200 for successful processing and 500 for genuine errors. Do not return 200 if the processing failed — this hides failures from Recuro’s monitoring.
Next steps
- Webhook Authentication — Implementation guide
- Webhook Signing — Technical reference
- HTTP Endpoint Design — Make your targets reliable