Amazon SNS message validation for PHP

Overview

Amazon SNS Message Validator for PHP

@awsforphp on Twitter Total Downloads Build Status Apache 2 License

The Amazon SNS Message Validator for PHP library allows you to validate that incoming HTTP(S) POST messages are valid Amazon SNS notifications. This library is standalone and does not depend on the AWS SDK for PHP or Guzzle; however, it does require PHP 5.4+ and that the OpenSSL PHP extension is installed.

Jump To:

Basic Usage

To validate a message, you can instantiate a Message object from the POST data using the Message::fromRawPostData. This reads the raw POST data from the php://input stream, decodes the JSON data, and validates the message's type and structure.

Next, you must create an instance of MessageValidator, and then use either the isValid() or validate(), methods to validate the message. The message validator checks the SigningCertURL, SignatureVersion, and Signature to make sure they are valid and consistent with the message data.



require 'vendor/autoload.php';

use Aws\Sns\Message;
use Aws\Sns\MessageValidator;
 
$message = Message::fromRawPostData();
 
// Validate the message
$validator = new MessageValidator();
if ($validator->isValid($message)) {
   // do something with the message
}

Installation

The SNS Message Validator can be installed via Composer.

$ composer require aws/aws-php-sns-message-validator

Getting Help

Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them.

About Amazon SNS

Amazon Simple Notification Service (Amazon SNS) is a fast, fully-managed, push messaging service. Amazon SNS can deliver messages to email, mobile devices (i.e., SMS; iOS, Android and FireOS push notifications), Amazon SQS queues,and — of course — HTTP/HTTPS endpoints.

With Amazon SNS, you can setup topics to publish custom messages to subscribed endpoints. However, SNS messages are used by many of the other AWS services to communicate information asynchronously about your AWS resources. Some examples include:

  • Configuring Amazon Glacier to notify you when a retrieval job is complete.
  • Configuring AWS CloudTrail to notify you when a new log file has been written.
  • Configuring Amazon Elastic Transcoder to notify you when a transcoding job changes status (e.g., from "Progressing" to "Complete")

Though you can certainly subscribe your email address to receive SNS messages from service events like these, your inbox would fill up rather quickly. There is great power, however, in being able to subscribe an HTTP/HTTPS endpoint to receive the messages. This allows you to program webhooks for your applications to easily respond to various events.

Handling Messages

Confirming a Subscription to a Topic

In order to handle a SubscriptionConfirmation message, you must use the SubscribeURL value in the incoming message:

use Aws\Sns\Message;
use Aws\Sns\MessageValidator;
use Aws\Sns\Exception\InvalidSnsMessageException;

// Instantiate the Message and Validator
$message = Message::fromRawPostData();
$validator = new MessageValidator();

// Validate the message and log errors if invalid.
try {
   $validator->validate($message);
} catch (InvalidSnsMessageException $e) {
   // Pretend we're not here if the message is invalid.
   http_response_code(404);
   error_log('SNS Message Validation Error: ' . $e->getMessage());
   die();
}

// Check the type of the message and handle the subscription.
if ($message['Type'] === 'SubscriptionConfirmation') {
   // Confirm the subscription by sending a GET request to the SubscribeURL
   file_get_contents($message['SubscribeURL']);
}

Receiving a Notification

To receive a notification, use the same code as the preceding example, but check for the Notification message type.

if ($message['Type'] === 'Notification') {
   // Do whatever you want with the message body and data.
   echo $message['MessageId'] . ': ' . $message['Message'] . "\n";
}

The message body will be a string, and will hold whatever data was published to the SNS topic.

Unsubscribing

Unsubscribing looks the same as subscribing, except the message type will be UnsubscribeConfirmation.

if ($message['Type'] === 'UnsubscribeConfirmation') {
    // Unsubscribed in error? You can resubscribe by visiting the endpoint
    // provided as the message's SubscribeURL field.
    file_get_contents($message['SubscribeURL']);
}

Testing Locally

One challenge of using webhooks in a web application is testing the integration with the service. Testing integrations with SNS notifications can be fairly easy using tools like ngrok and PHP's built-in webserver. One of our blog posts, Testing Webhooks Locally for Amazon SNS, illustrates a good technique for testing.

NOTE: The code samples in the blog post are specific to the message validator in Version 2 of the SDK, but can be easily adapted to using this version.

Special Thank You

A special thanks goes out to Julian Vidal who helped create the initial implementation in Version 2 of the AWS SDK for PHP.

Contributing

We work hard to provide a high-quality and useful SDK for our AWS services, and we greatly value feedback and contributions from our community. Please review our contributing guidelines before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution.

Comments
  • Error:

    Error: "Message" is required to verify the SNS Message

    Same error of that mentioned in #29, this issue has plagued me as well, in particular when sending SNS Notifications via Elastic Transcoder. Elastic Transcoder Notification payloads don't seem to contain a "Message" field. Is there any work around's to this?

    Here is an example of an Elastic Transcoder Notification, recieved via E-Mail:

    {
      "state" : "COMPLETED",
      "version" : "2012-09-25",
      "jobId" : "1559924750698-dejdio",
      "pipelineId" : "1559968916611-abcdef",
      "input" : {
        "key" : "MySong.mp3",
        "container" : "auto"
      },
      "inputCount" : 1,
      "outputs" : [ {
        "id" : "1",
        "presetId" : "1351620000001-100110",
        "key" : "MySong.m4a",
        "thumbnailPattern" : "",
        "rotate" : "auto",
        "status" : "Complete",
        "duration" : 157
      } ]
    }
    
    service-api guidance 
    opened by j-braun0384 5
  • Split up missing and invalid certificate errors

    Split up missing and invalid certificate errors

    The Cannot get the public key from the certificate. error gets thrown in these circumstances:

    • When openssl_pkey_get_public can't extract the key and returns false.
    • When the certClient can't read the certificate.

    The latter happens fairly regularly because of network issues. When using the default certClient (file_get_contents) the $certificate variable will contain false (and a PHP Warning will get logged). Could this get checked separately from the first circumstance?

    A possible issue is a custom certClient which returns something different. On the other hand, having $certificate === false throw a separate error sounds quite harmless.

    I'm happy to send a PR if this sounds good.

    opened by smhg 5
  • Allow Aws\Sns\Message

    Allow Aws\Sns\Message

    Allow usage of Aws\Sns\Messageinstead of limiting to Aws\Sns\MessageValidator\Message. This should be essentially the same.

    Can be fixed by moving the typecheck into the method. Do you want me to send a pull-request?

    opened by ckrack 5
  • Handling HTTP failures gracefully

    Handling HTTP failures gracefully

    https://sns.us-east-1.amazonaws.com/SimpleNotificationService-bb750dd426d95ee9390147a5624348ee.pem): failed to open stream: HTTP request failed! HTTP/1.1 503 Service Unavailable Warning at line 60 in /var/www/html/vendor/aws/aws-php-sns-message-validator/src/MessageValidator.php

    There is no way to catch this error.

    guidance 
    opened by schulzrinne 5
  • InvalidArgumentException:

    InvalidArgumentException: "Message" is required to verify the SNS Message.

    i'm using laravel for getting sns messages everything is fine but when i'm getting post request it's throwing error like "InvalidArgumentException: "Message" is required to verify the SNS Message." i followed the document exactly. please tell me did i miss anything?

    guidance 
    opened by thanush 4
  • PHP 8.1 Compatibility

    PHP 8.1 Compatibility

    Please fill out the sections below to help us address your issue.

    Version of AWS SDK for PHP?

    N/A

    Version of Amazon SNS Message Validator for PHP?

    1.6.0

    Version of PHP (php -v)?

    8.1rc1

    What issue did you see?

    PHP Fatal error: During inheritance of ArrayAccess: Uncaught ErrorException: Return type of Aws\Sns\Message::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/runner/work/laravel-aws-sns/laravel-aws-sns/vendor/aws/aws-php-sns-message-validator/src/Message.php:100

    Steps to reproduce

    This is a run-time failure due to a signature validation error any time the method is invoked.

    Additional context

    We identified this issue when attempting to validate a package using the message validator against PHP 8.1rc1. We will be submitting a pull request in the future to resolve this issue.

    opened by wardtd 3
  • Installing from Source

    Installing from Source

    Hi -

    Thanks for this validator. My endpoints have been operating manually without the SDK for some time and i really want to get a validator back online. I am getting constant errors when i try to install this through composer, and i am looking for some guidance on where to install it if i am going to install it from the source.

    Please let me know if this makes sense when you have a chance.

    opened by bkoffler 3
  • SNS message type header not provided.

    SNS message type header not provided.

    Hi,

    First of all I wanna thank you for sharing the code with us.

    But when I run the code i get the following error:

    Fatal error: Uncaught exception 'RuntimeException' with message 'SNS message type header not provided.' in /home/communiq/domains/millows.communiq.nl/public_html/aws/vendor/aws/aws-php-sns-message-validator/src/Message.php:33

    Stack trace: #0 /home/communiq/domains/millows.communiq.nl/public_html/aws/SimpleNotificationService.php(46): Aws\Sns\Message::fromRawPostData() #1 {main} thrown in /home/communiq/domains/millows.communiq.nl/public_html/aws/vendor/aws/aws-php-sns-message-validator/src/Message.php on line 33

    The subscription is already confirmed..

    Could you please help me out here?

    opened by EdingerMike 3
  • Php 8.1 support

    Php 8.1 support

    *Issue #54

    *Description of changes: Added method return types as required for PHP 8.1 compatibility

    By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

    opened by wardtd 2
  • Mute warning when file_get_contents() fails

    Mute warning when file_get_contents() fails

    Issue #, if available:

    none.

    Description of the issue:

    Currently, the library uses file_get_contents() by default to retrieve the SigningCertURL. It assumes that this function just returns false when it fails. But it actually also issues a warning, for example:

    Warning: file_get_contents(): php_network_getaddresses: getaddrinfo failed: Name or service not known

    This is an issue when you have configured an error handler to convert all warnings to exceptions (for example, in Symfony when using framework.php_errors.throw), in which case you get an uncaught erorr exception instead of an InvalidSnsMessageException, as this code can never be reached.

    Description of changes:

    This PR does two things:

    • Replace file_get_contents() with a closure that prepends the mute operator @ to the function; so the function will always return a string or false as expected, but never trigger a warning
    • Clarify the $certClient callable return type, which is expected to return string|false, not just string

    By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

    opened by BenMorel 2
  • failed to open stream

    failed to open stream

    This is an issue with my host setup, but hoping someone can steer me in the right direction. I'm seeing the following warnings in my logs. Lots of chatter about missing ca certificates possibly? I'm running centos CentOS Linux release 7.3 and AWS php sdk 3.29.7.

    Somehow the SNS still appears to be processed, but how do I fix my setup here?

    • file_get_contents(): SSL: Connection reset by peer
    • file_get_contents(): Failed to enable crypto
    • file_get_contents(https://sns.us-west-2.amazonaws.com/SimpleNotificationService): failed to open stream: operation failed /vendor/aws/aws-php-sns-message-validator/src/MessageValidator.php
    guidance 
    opened by Zelfapp 2
  • psr/http-message is not required

    psr/http-message is not required

    Issue

    The package psr/http-message is installed even if it's not used. The class Psr\Http\Message\RequestInterface don't have to exist to be used as argument type of an optional method. https://github.com/aws/aws-php-sns-message-validator/blob/97501cf382af53818161c156a8af07c073889577/src/Message.php#L53-L56

    Description of changes

    Remove the dependency. It will continue to be installed on projects that require implementations (tests uses guzzlehttp/psr7)

    By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

    opened by GromNaN 0
  • PHP Fatal error:  Uncaught RuntimeException: SNS message type header not provided.

    PHP Fatal error: Uncaught RuntimeException: SNS message type header not provided.

    Please fill out the sections below to help us address your issue.

    Version of AWS SDK for PHP?

    "aws/aws-sdk-php": "~2.6.0",

    Version of Amazon SNS Message Validator for PHP?

    "aws/aws-php-sns-message-validator": "^1.6"

    Version of PHP (php -v)?

    PHP 7.2.34

    What issue did you see?

    when executing I get the following message:

    PHP Fatal error: Uncaught RuntimeException: SNS message type header not provided. in /var/www/vhosts/studio/vendor/aws/aws-php-sns-message-validator/src/Message.php:40 Stack trace:

    0 /var/www/vhosts/studio/index.php(8): Aws \ Sns \ Message :: fromRawPostData ()

    1 {main}

    thrown in /var/www/vhosts/studio/vendor/aws/aws-php-sns-message-validator/src/Message.php on line 40

    Steps to reproduce

    If you have a runnable example, please include it as a snippet or link to a repository/gist for larger code examples.

    I install sdk through composer, and I send it to call in an index.php file, is:

    require 'vendor/autoload.php';

    use Aws\Sns\Message; use Aws\Sns\MessageValidator; use Aws\Sns\Exception\InvalidSnsMessageException;

    // Instantiate the Message and Validator $message = Message::fromRawPostData(); $validator = new MessageValidator();

    // Validate the message and log errors if invalid. try { $validator->validate($message); } catch (InvalidSnsMessageException $e) { // Pretend we're not here if the message is invalid. http_response_code(404); error_log('SNS Message Validation Error: ' . $e->getMessage()); die(); }

    // Check the type of the message and handle the subscription. if ($message['Type'] === 'SubscriptionConfirmation') { // Confirm the subscription by sending a GET request to the SubscribeURL file_get_contents($message['SubscribeURL']); }

    Additional context

    Any additional information relevant to the issue. Examples include any framework you may be using (e.g. Laravel, Wordpress) in conjunction with the AWS SDK for PHP, or PHP/environment config settings if the issue is related to memory or performance.

    opened by gioutn19 0
  • Add closed issue message github action

    Add closed issue message github action

    Issue #, if available: N/A

    Description of changes:

    • Add a Github Action which sets a default message that will be commented on all issues when they get closed to warn users that comments on closed issues are hard for our team to see.

    comment-example

    This is an OSDS effort across all SDKs&Tools repos to address the issue of customers expecting a response from AWS when they comment on closed issues.

    By setting this default message we are clarifying expectations and explaining Github's limitation instead of letting users assume we are willfully ignoring them. We are giving clear directives about how to notify us and we're giving customers agency to make their own informed decisions as to whether or not they want to comment on closed issues.


    By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

    opened by SomayaB 0
  • Most SNS Notifications won't pass validation

    Most SNS Notifications won't pass validation

    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();

    bug 
    opened by tornadotwins 10
  • Add a Guzzle certificate client and add Guzzle 6 as a suggested dependency

    Add a Guzzle certificate client and add Guzzle 6 as a suggested dependency

    file_get_contents triggers errors and warnings rather than throwing exceptions, which can make recovering from a failure state tricky. This PR adds Guzzle as an optional dependency and provides a client that matches the interface expected by Aws\Sns\MessageValidator. Since Guzzle will also use cURL if it's available, this PR should resolve #23

    /cc @kstich

    no-pr-activity 
    opened by jeskew 4
Releases(1.8.0)
  • 1.8.0(Aug 22, 2022)

  • 1.7.0(Apr 22, 2022)

  • 1.6.0(Nov 8, 2019)

  • 1.5.0(Jul 4, 2018)

  • 1.4.0(Sep 27, 2017)

  • 1.3.0(Aug 29, 2017)

  • 1.2.0(Jul 12, 2017)

  • 1.1.0(Sep 3, 2015)

    This library now allows overriding of the host pattern used to verify that SNS signing certs are hosted on a trusted domain. The default pattern remains /^sns\.[a-zA-Z0-9\-]{3,}\.amazonaws\.com(\.cn)?$/, but it can be set to any pattern for testing.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Jul 6, 2015)

    Amazon SNS Message Validator

    The Amazon SNS Message Validator for PHP library allows you to validate that incoming HTTP(S) POST messages are valid Amazon SNS notifications. This library is standalone and does not depend on the AWS SDK for PHP or Guzzle; however, it does require PHP 5.4+ and that the OpenSSL PHP extension is installed.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jun 30, 2015)

    Initial pre-release of the Amazon SNS Message Validator for PHP.

    The code for this package was extracted from Version 2 of the AWS SDK for PHP, and then refactored to remove dependencies on the SDK and Guzzle. This library requires PHP 5.4+ and OpenSSL.

    Source code(tar.gz)
    Source code(zip)
Owner
Amazon Web Services
Amazon Web Services
Facebook GraphQL for Laravel 5. It supports Relay, eloquent models, validation and GraphiQL.

Laravel GraphQL This package is no longuer maintained. Please use rebing/graphql-laravel or other Laravel GraphQL packages Use Facebook GraphQL with L

Folklore Inc. 1.8k Dec 11, 2022
⚡️ Web3 PHP is a supercharged PHP API client that allows you to interact with a generic Ethereum RPC.

Web3 PHP is a supercharged PHP API client that allows you to interact with a generic Ethereum RPC. This project is a work-in-progress. Code and docume

Web3 PHP 665 Dec 23, 2022
Lightweight PHP library for WhatsApp API to send the whatsapp messages in PHP provided by ultramsg.com

Ultramsg.com WhatsApp API PHP SDK Lightweight PHP library for WhatsApp API to send the whatsappp messages in PHP provided by Ultramsg.com Installation

Ultramsg 117 Dec 26, 2022
Google-api-php-client - A PHP client library for accessing Google APIs

Google APIs Client Library for PHP Reference Docs https://googleapis.github.io/google-api-php-client/main/ License Apache 2.0 The Google API Client Li

Google APIs 8.4k Dec 30, 2022
Wise-php - This library is written to accommodate the wise API's use in php projects With Wise

Wise-php - This library is written to accommodate the wise API's use in php projects With Wise you can automate payments, connect your business tools, and create ways to manage your finances. You can also power your cross-border and domestic payouts.

Albert Xhani 15 Nov 17, 2022
It's a PHP Application to simplify working with Google Sheets SDK for php.

About GoogleSheetsPHP It's a PHP Application to simplify working with Google Sheets SDK for php. Note: i used Slim 3 to construct the application but

Sami Alateya 5 Dec 20, 2022
Official repository of the AWS SDK for PHP (@awsforphp)

AWS SDK for PHP - Version 3 The AWS SDK for PHP makes it easy for developers to access Amazon Web Services in their PHP code, and build robust applica

Amazon Web Services 5.7k Jan 1, 2023
A framework agnostic PHP library to build chat bots

BotMan If you want to learn how to create reusable PHP packages yourself, take a look at my upcoming PHP Package Development video course. About BotMa

BotMan 5.8k Jan 3, 2023
PHP library for the Stripe API.

Stripe PHP bindings The Stripe PHP library provides convenient access to the Stripe API from applications written in the PHP language. It includes a p

Stripe 3.3k Jan 5, 2023
A simple PHP GitHub API client, Object Oriented, tested and documented.

PHP GitHub API A simple Object Oriented wrapper for GitHub API, written with PHP. Uses GitHub API v3 & supports GitHub API v4. The object API (v3) is

KNP Labs 2k Jan 7, 2023
A PHP library for communicating with the Twilio REST API and generating TwiML.

twilio-php The default branch name for this repository has been changed to main as of 07/27/2020. Documentation The documentation for the Twilio API c

Twilio 1.4k Jan 2, 2023
Mailgun's Official SDK for PHP

Mailgun PHP client This is the Mailgun PHP SDK. This SDK contains methods for easily interacting with the Mailgun API. Below are examples to get you s

Mailgun Team 1k Dec 23, 2022
A PHP library for the Campaign Monitor API

createsend A PHP library which implements the complete functionality of the Campaign Monitor API. Installation Composer If you use Composer, you can r

Campaign Monitor 287 Jan 6, 2023
PHP 5.3+ library which helps you to interact with the DigitalOcean API

DigitalOcean The version 2 of the API will be available soon ! Please visit DigitalOceanV2 and contribute :) This PHP 5.3+ library helps you to intera

Antoine Kirk 156 Jul 30, 2022
A versatile PHP Library for Google PageSpeed Insights

PhpInsights An easy-to-use API Wrapper for Googles PageSpeed Insights. The JSON response is mapped to objects for an headache-free usage. Installation

Daniel Sentker 110 Dec 28, 2022
PHP library for the GitHub API v3

GitHub API v3 - PHP Library Currently under construction. Overview Provides access to GitHub API v3 via an Object Oriented PHP library. The goal of th

Darren Rees 62 Jul 28, 2022
Twitter REST API for PHP 5.3+

README The Wid'op Twitter REST library is a modern PHP 5.3+ API allowing you to easily interact with Twitter 1.1. In order to sign your request with t

Wid'op 24 Aug 10, 2020
PHP library to use IOTA REST API to help node management and tangle queries

iota.php About PHP library to use IOTA REST API to help node management and tangle queries. Please be aware that this library is in an early developme

IOTA Community 45 Dec 13, 2022
A simple Object Oriented PHP Client for Termii SMS API

Termii Client A simple Object Oriented PHP Client for Termii SMS API. Uses Termii API. Requirements PHP >= 7.2 Guzzlehttp ~6|~7 Installation Via Compo

Ilesanmi Olawale Adedotun 5 Feb 24, 2022