Verify AWS SNS Signatures in PHP
Verify AWS SNS Signatures in PHP
SNS messages must be verified before processing to prevent spoofing. This guide shows how to validate SigningCertURL, verify signatures (v1/v2), pin TopicArn, and safely confirm subscriptions using the AWS PHP SNS Message Validator. The primary keyword aws sns signature verification php is used in examples and test steps.
You will add middleware that uses AWS’s MessageValidator, pin TopicArn, and fail closed on invalid signatures.
Why SNS signature verification is non-negotiable
SNS messages can be delivered by anyone who can post to your endpoint — signature verification prevents spoofed notifications.
Spoofing risks
Without verification, attackers can send fake notifications that trigger downstream workflows.
TopicArn pinning
Pin expected TopicArn values to avoid accepting messages from unauthorized topics.
Micro checklist:
- Always verify signatures before processing.
- Pin
TopicArnwhere possible.- Confirm subscription messages only after verification.
SNS signature versions + best practices
Be aware of signature versions and always fetch signing certs over HTTPS from AWS domains.
v2 (SHA256) vs v1 (SHA1)
Prefer v2 (SHA256) when available; validator libraries support both.
Always fetch signing cert via HTTPS + validate domain
Only fetch signing certificates from sns.amazonaws.com or other trusted AWS domains.
Reject unexpected TopicArn
If TopicArn does not match your expected value, reject the message.
Common gotcha: Accepting arbitrary
SigningCertURLvalues without domain validation exposes you to certificate substitutions.
Recommended implementation: AWS PHP SNS Message Validator
Use the official library to validate messages and handle SubscriptionConfirmation safely.
Composer install + prerequisites
| |
Middleware pattern in Laravel
Use raw JSON string to build Message objects and validate with MessageValidator.
Handling SubscriptionConfirmation safely
Confirm subscriptions only after MessageValidator returns valid.
Suggested diagram: Flowchart showing raw JSON → Message::fromJsonString → MessageValidator::isValid → accept/reject.
Local testing strategy
Fail closed in local tests and use real SNS publishes for end-to-end verification.
“Fail closed” curl test
Reject invalid signatures and return 401 in test cases so test coverage mirrors production.
End-to-end test via real SNS publish
Publish a test message in the console or CLI and validate it arrives and is processed after signature verification.
Required code snippets
B) Middleware (Laravel) using raw body
| |
C) Apply to your SES SNS endpoint
| |
Test steps (curl + expected response)
- Invalid signature (should fail closed)
| |
Expected: 401 invalid sns signature
- Real publish test
- Publish a test message to the SNS topic (console or CLI). Your endpoint should return 204 and process it once signature validation passes.
Common failure modes
- Not verifying SigningCertURL trust (accepting attacker-provided cert URL).
- Not pinning TopicArn (accepting messages from other topics).
- Validating after processing (side effects before auth).
- Reading/mutating body before validation (use raw JSON string path).
- Ignoring SubscriptionConfirmation (you never confirm subscription, so no notifications arrive).
Related
- /docs/guides/aws-ses-sns-event-notifications — Set up SES → SNS notifications
- /docs/guides/email-provider-event-webhooks — Email provider events overview
- /docs/webhooks/ — Retries, dedupe, and webhook hardening
Verify once, trust downstream: after signature checks pass, forward events into SendPromptly and inspect the run details. Open Sample Project · Open Message Log
Conclusion
- Use AWS’s MessageValidator library to validate SNS messages.
- Pin
TopicArnand validateSigningCertURLdomains. - Fail closed on invalid signatures and confirm subscriptions securely.
- Test with a real SNS publish for end-to-end verification.