Closed skunkworker closed 6 years ago
Same here. This exception occurs several times daily recently (curiously no error's detected today). I have saved a set of url, parameters, and X-Twilio-Signature value to reproduce this error so if you want to take a deeper look feel free to reach me (I think revealing my phone number here is not a good idea).
if request.post?
validator = Twilio::Security::RequestValidator.new Settings.auth_token
signature = request.headers['X-Twilio-Signature']
unless validator.validate(request.url, request.request_parameters, signature)
raise 'Invalid request'
end
end
Hello, sorry you're having trouble with signature validation.
@skunkworker, if this is only failing for transcription callbacks, then it's not an issue with the helper library. Please submit a ticket to our Support team to investigate why your transcription callbacks contain unexpected signatures.
@yagitoshiro, you're right, revealing your phone number here is not a good idea, so please submit a ticket to our Support team to share the details for reproducing the issue.
For what it's worth, every issue with signature validation I've investigated has been due to a data/input issue, not a bug in the helper library. Please work with the Support team to investigate further and we can reopen this issue if they find there is indeed a bug needing to be addressed in the library.
Edit: Contact the Support Team at https://www.twilio.com/help/contact
All the Best,
Zack
To someone still searching for the answer to this problem:
My example was derived from a Rails app. And my problem was caused by my improper usage of Rails' request.url
, which removes trailing slash automatically even when Twilio sends post requests to the url with trailing slash. I modified my code like this:
validator = Twilio::Security::RequestValidator.new auth_token
signature = request.headers['X-Twilio-Signature']
unless validator.validate(request.original_url, request.request_parameters, signature)
raise 'invalid request'
end
Hope it helps.
Thanks @yagitoshiro.
So my old validator method was doing a transform instead of getting the raw request parameters.
For Rails 5.2
NOT CORRECT: params.reject { |k, _| k.downcase == k }
where I should have been doing:
CORRECT:request.request_parameters
This solved the issue.
Edit: https://github.com/twilio/twilio-ruby/wiki/Request-Validator is where I got the fixed validator.
Below is a working validator method for Rails 5.2.2 confirmed, probably all Rails 5, Rails 4 unsure.
def twilio_req?
load_credentials
# First, instantiate a RequestValidator object with your account's AuthToken.
validator = Twilio::Security::RequestValidator.new(@twilio_token)
# Then gather the data required to validate the request. The following works in
# sinatra, and something similar should work in any rack-based environment.
# Build the URI for this request, including query string params if any.
uri = request.original_url
# Collect all parameters passed from Twilio.
params = request.request_parameters
# If GET, use rack.request.query_hash instead:
# params = env['rack.request.query_hash']
#
# for POST or request.request_parameters
# params = env['rack.request.form_hash']
# Grab the signature from the HTTP header.
signature = request.headers['X-Twilio-Signature']
# Finally, call the validator's #validate method.
validator.validate uri, params, signature #=> true if the request is from Twilio
end```
Just as a tip for both of you, this gem has a rack middleware for validating requests. You can drop it into your config/environments/production.rb
file like so:
Rails.application.configure do
# Other Rails config
config.middleware.use Rack::TwilioWebhookAuthentication, ENV['TWILIO_AUTH_TOKEN'], '/messages'
end
And it will protect the URL patterns you provide it in the arguments. Check out the code here and a blog post describing how to use it here.
I've been working on adding twilio phone callbacks to an app. I added the request validator to authenticate the incoming requests and for my main request url, voicemail callback, SMS (all using the same code, but unrelated), the authenticator works just fine. When the recording done callback comes in, the request is validated. But when a recording transcription call comes in, the request doesn't match the signature.
Version:
twilio-ruby (5.15.1)
Code Snippet
Exception/Log
Steps to Reproduce
request.url, post_vars, signature
don't match.