aws / aws-php-sns-message-validator

Amazon SNS message validation for PHP
Apache License 2.0
209 stars 52 forks source link

Most SNS Notifications won't pass validation #44

Closed tornadotwins closed 4 weeks ago

tornadotwins commented 4 years ago

SNS Notifications that come from, for example, SES (like complaints and bounce notifications), don't have a 'Message' key/object at the root of the JSON payload. The same goes for 'MessageId', 'Timestamp', etc. Elastic Transcoder messages can have the same missing fields.

This will result in the Message class to not pass the given JSON object, before it even goes to validation.

The required fields can be found in Message.php, line 11. The Exception that gets thrown can be found in Message.php, line 151.

How to reproduce: Simply receive an SNS notification using: $message = Message::fromRawPostData();

connecteev commented 4 years ago

Seeing the same thing. None of my incoming SNS notifications (triggered by an email send via SES) are passing validation. I tried re-creating the SNS Topic and Subscription but nothing seems to work.

[2019-11-02 04:31:23] local.ERROR: "Message" is required to verify the SNS Message. {"exception":"[object] (InvalidArgumentException(code: 0): \"Message\" is required to verify the SNS Message. at //jdavidbakr_mail_tracker/vendor/aws/aws-php-sns-message-validator/src/Message.php:150)
[stacktrace]
#0 //jdavidbakr_mail_tracker/vendor/aws/aws-php-sns-message-validator/src/Message.php(85): Aws\\Sns\\Message->validateRequiredKeys(Array, Array)
#1 //jdavidbakr_mail_tracker/vendor/aws/aws-php-sns-message-validator/src/Message.php(71): Aws\\Sns\\Message->__construct(Array)
#2 //jdavidbakr_mail_tracker/vendor/aws/aws-php-sns-message-validator/src/Message.php(44): Aws\\Sns\\Message::fromJsonString('{\"notificationT...')
#3 //jdavidbakr_mail_tracker/vendor/jdavidbakr/mail-tracker/src/SNSController.php(42): Aws\\Sns\\Message::fromRawPostData()
#4 [internal function]: jdavidbakr\\MailTracker\\SNSController->callback(Object(Illuminate\\Http\\Request))
#5 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#6 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('callback', Array)
#7 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(jdavidbakr\\MailTracker\\SNSController), 'callback')
#8 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\\Routing\\Route->runController()
#9 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\\Routing\\Route->run()
#10 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#11 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#12 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#13 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(76): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#14 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#15 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#17 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(56): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#18 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#19 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#20 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#21 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#22 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(171): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#23 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#24 //jdavidbakr_mail_tracker/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
connecteev commented 4 years ago

@tornadotwins did you figure out whats wrong?

tornadotwins commented 4 years ago

@connecteev Well, the messages aren't passing validation because the class was written when AWS formatted their messages differently. We're getting completely different data back from AWS, so they won't pass validation, because the variables this class is looking for don't exist or are formatted differently.

I ended up writing my own class, because updating this one to fit multiple message structures would have been just as much work as just writing one from scratch.

connecteev commented 4 years ago

@tornadotwins thanks...i ended up rewriting code too. not fun

chopstik commented 4 years ago

I'm seeing this Exception as well - same scenario SES generated SNS notifications: Deliveries

howardlopez commented 4 years ago

@chopstik @tornadotwins Can you provide exact steps to produce a service's SNS notification that fails validation? I've tested with a couple Elastic Transcoder calls and an SES delivery notification, sent it to a test server subscribed via the HTTP protocol, and they've been passing. For example, for an SES delivery:

Array
(
    [Type] => Notification
    [MessageId] => [REDACTED]
    [TopicArn] => [REDACTED]
    [Message] => {"notificationType":"Delivery","mail": [REDACTED]}
    [Timestamp] => 2019-12-06T00:27:45.245Z
    [SignatureVersion] => 1
    [Signature] => [REDACTED]
    [SigningCertURL] => https://sns.us-west-2.amazonaws.com/SimpleNotificationService-[REDACTED]
    [UnsubscribeURL] => https://sns.us-west-2.amazonaws.com/?[REDACTED]
)
tornadotwins commented 4 years ago

Apologies for the late reply, but you could try and use any standard complaint/bounce/etc coming back from S.E.S. Example for a bounce: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-examples.html Example for a complaint: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-examples.html#notification-examples-complaint

Hope that helps!

tcopestake commented 4 years ago

I don't know if this explains the issue you've all been having, but I had a similar problem when I inadvertently enabled raw message delivery on the subscription; that seems to omit all of the usual message structure. Everything worked fine again when I disabled it.

rennokki commented 4 years ago

@tcopestake Man... 🤦‍♂️ Just found out that raw message delivery strips off all metadata.

AliHassan82 commented 2 years ago

I don't know if this explains the issue you've all been having, but I had a similar problem when I inadvertently enabled raw message delivery on the subscription; that seems to omit all of the usual message structure. Everything worked fine again when I disabled it.

@tcopestake Thanks man..!! you save my day.

RanVaknin commented 1 month ago

Hi everyone on the thread.

It seems like this message have unblocked many of you. Is this issue still persistent after the context given in that comment?

Thanks, Ran~

github-actions[bot] commented 1 month ago

This issue has not recieved a response in 1 week. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.