Menu

Expand
Rate this page:

Secure your Flask App by Validating Incoming Twilio Requests

In this guide we’ll cover how to secure your Flask application by validating incoming requests to your Twilio webhooks are, in fact, from Twilio.

With a few lines of code we’ll write a custom decorator for our Flask app that uses the Twilio Python SDK’s validator utility. We can then use that decorator on our Flask views which accept Twilio webhooks to confirm that incoming requests genuinely originated from Twilio.

Let’s get started!

Create a custom decorator

The Twilio Python SDK includes a RequestValidator class we can use to validate incoming requests.

We could include our request validation code as part of our Flask views, but this is a perfect opportunity to write a Python decorator. This way we can reuse our validation logic across all our views which accept incoming requests from Twilio.

Loading Code Sample...
        
        
        Confirm incoming requests to your Flask views are genuine with this custom decorator.

        Custom decorator for Flask apps to validate Twilio requests

        Confirm incoming requests to your Flask views are genuine with this custom decorator.

        To validate an incoming request genuinely originated from Twilio, we first need to create an instance of the RequestValidator class using our Twilio auth token. After that we call its validate method, passing in the request’s URL, payload, and the value of the request's X-TWILIO-SIGNATURE header.

        That method will return True if the request is valid or False if it isn’t. Our decorator then either continues processing the view or returns a 403 HTTP response for inauthentic requests.

        If you are passing query string parameters in the URLs used in the webhooks you are validating, you may need to take extra care to encode or decode the URL so that validation passes. Some web frameworks like Flask will sometimes automatically unescape the query string part of the request URL, causing validation to fail.

        Use the Decorator with our Twilio Webhooks

        Now we’re ready to apply our decorator to any view in our Flask application that handles incoming requests from Twilio.

        Loading Code Sample...
              
              
              Apply a custom Twilio request validation decorator to a Flask view used for Twilio webhooks.

              Apply the request validation decorator to a Flask view

              Apply a custom Twilio request validation decorator to a Flask view used for Twilio webhooks.

              To use the decorator with an existing view, just put @validate_twilio_request above the view’s definition. In this sample application we use our decorator with two views: one that handles incoming phone calls and another that handles incoming text messages.

              If your Twilio webhook URLs start with `https://` instead of `http://`, your request validator may fail locally when you use Ngrok or in production if your stack terminates SSL connections upstream from your app. This is because the request URL that your Flask application sees does not match the URL Twilio used to reach your application.

              To fix this for local development with Ngrok, use `http://` for your webook instead of `https://`. To fix this in your production app, your decorator will need to reconstruct the request's original URL using request headers like `X-Original-Host` and `X-Forwarded-Proto`, if available.

              Disable Request Validation During Testing

              If you write tests for your Flask views those tests may fail for views where you use your Twilio request validation decorator. Any requests your test suite sends to those views will fail the decorator’s validation check.

              To fix this problem we recommend adding an extra check in your decorator, like so, telling it to only reject incoming requests if your app is running in production.

              Loading Code Sample...
                    
                    
                    Use this version of the custom Flask decorator if you test your Flask views.

                    An improved Flask request validation decorator, useful for testing

                    Use this version of the custom Flask decorator if you test your Flask views.

                    Test the validity of your webhook signature

                    It's a great idea to run automated testing against your webhooks to ensure that their signatures are secure. The following Python code can test your unique endpoints against both valid and invalid signatures.

                    To make this test work for you, you'll need to:

                    1. Set your Auth Token as an environment variable
                    2. Set the URL to the endpoint you want to test
                    3. If testing BasicAuth, change HTTPDigestAuth to HTTPBasicAuth
                    Loading Code Sample...
                          
                          
                          This sample test will test the validity of your webhook signature with HTTP Basic or Digest authentication.

                          Test the validity of your webhook signature

                          This sample test will test the validity of your webhook signature with HTTP Basic or Digest authentication.

                          What’s next?

                          Validating requests to your Twilio webhooks is a great first step for securing your Twilio application. We recommend reading over our full security documentation for more advice on protecting your app, and the Anti-Fraud Developer’s Guide in particular.

                          To learn more about securing your Flask application in general, check out the security considerations page in the official Flask docs.

                          Andrew Baker David Prothero Kevin Whinnery Kat King Jose Oliveros Greg Parker Paul Kamp Sarah Stringer Daniel Erazo
                          Rate this page:

                          Need some help?

                          We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

                          Loading Code Sample...
                                
                                
                                

                                Thank you for your feedback!

                                Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

                                Sending your feedback...
                                🎉 Thank you for your feedback!
                                Something went wrong. Please try again.

                                Thanks for your feedback!

                                thanks-feedback-gif