Skip to content

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:

  1. Deploy your updated endpoint code with the new secret first (or support both old and new secrets temporarily)
  2. Regenerate the secret in the dashboard
  3. 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:

CodeMeaning to Recuro
200-299Success — execution marked as completed (subject to assertions)
400-499Client error — execution marked as failed with http_client_error
500-599Server 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