Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhook Signature Verification #90

Merged
merged 5 commits into from Aug 29, 2017

Conversation

mjc-gh
Copy link
Contributor

@mjc-gh mjc-gh commented Aug 26, 2017

Closes #83.

This to do for this PR:

  • Update the README
  • Get my specs running and add a few for this feature

@coveralls
Copy link

coveralls commented Aug 26, 2017

Coverage Status

Coverage decreased (-3.0%) to 96.269% when pulling 546e454 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage decreased (-3.0%) to 96.269% when pulling 546e454 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-3.0%) to 96.269% when pulling 546e454 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

@rmm5t
Copy link
Member

rmm5t commented Aug 27, 2017

  • Add deprecation errors and/or warnings for removal of StripeEvent.authentication_secret

Let's keep things focused. Please don't remove or or change the behavior of the authentication_secret as part of this pull-request. Let's only consider deprecating it after we get signature verification fully working and released. The deprecation deserves to be part of a separate PR later.

@mjc-gh
Copy link
Contributor Author

mjc-gh commented Aug 27, 2017

Sounds good. Had only included it in this PR cause the original issue mentioned that authentication_secret can be deprecated. I will remove that portion of the PR and keep both features in place.

Need to get the specs running locally so I can add some for this feature. Was having bundler version issues when I tried to run them initially.

@mjc-gh mjc-gh force-pushed the webhook-signature-verification branch from 546e454 to d2dbb83 Compare August 28, 2017 00:18
@coveralls
Copy link

coveralls commented Aug 28, 2017

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling d2dbb83 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

This configuration value is used to verify the cryptographic signature
of a Stripe webhook. This commit also updates the webhook controller to
verify the signature. See Stripe for more details:

https://stripe.com/docs/webhooks#signatures
@mjc-gh mjc-gh force-pushed the webhook-signature-verification branch from d2dbb83 to 4b59c76 Compare August 28, 2017 00:33
@coveralls
Copy link

coveralls commented Aug 28, 2017

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 4b59c76 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

@rmm5t
Copy link
Member

rmm5t commented Aug 28, 2017

Thanks for making the adjustments to this PR. Looks clean. Have you tried this branch against a live Stripe endpoint yet?

My only critique is that I'd prefer the tests to pass an actual HMAC signature header instead of mocking the call to Stripe::Webhook::Signature.verify_header (I prefer a classical style of testing where possible vs a mockist style), but there's no need for that to hold up this PR.

I can merge and release a new version later today if no one else objects.

Good work @mikeycgto!

@mjc-gh
Copy link
Contributor Author

mjc-gh commented Aug 28, 2017

Thanks!

Yeah I do agree with you and prefer to avoid mocking when possible. My concern there was the specs would become to specific to actual the HMAC implementation in Stripe. Figured mocks would just be quicker to write and more future-proof if their verification process changes (assuming the API doesn't change 😃).

@brandur
Copy link

brandur commented Aug 28, 2017

@rmm5t @mikeycgto Nice! I'd +1 trying to go a level deeper than the mock if possible. What you can do in this case is to call Stripe::Webhook::Signature.compute_signature(payload, secret) to generate a valid signature before validating it.

That way you can test more deeply than the mock and you don't have to rely on any particular crypto implementation — if we update to something beyond HMAC-SHA256, we'll be updating .compute_signature as well .verify_header within stripe-ruby.

@mjc-gh
Copy link
Contributor Author

mjc-gh commented Aug 28, 2017

@brandur this was more involved than I thought it would be (have to include a timestamp and version scheme). I do agree it's better to use real signatures here though. Thanks for the feedback!

@coveralls
Copy link

coveralls commented Aug 28, 2017

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 806c572 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

Copy link

@brandur brandur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Left a couple comments below.

(BTW, just so it's clear, I don't have any direct involvement in this project, and just took a look because a related thread had been bumped with this PR. I fully defer to the real maintainers on all things.)

after(:each) { StripeEvent.signing_secret = nil }

it "rejects invalid signatures" do
webhook_with_signature generate_signature('invalid payload'), id: 'evt_charge_succeeded'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I don't think I fully understand this test. Why does this one come out as invalid with the one below valid? It seems that it should be computing a valid signature for any value that you send to #generate_signature shouldn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I shouldn't use generate_signature? I wanted to have a spec that passes the correct format with the timestamp but with an incorrect signature. Maybe I should just pass a string directly here like so:

webhook_with_signature "t=#{timestamp},v1=invalid", id: 'evt_charge_succeeded'

Perhaps a better spec would be to "reject missing signature" where no header is provided? Any suggestions here @rmm5t?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest just passing in a "bogus" signature string and avoid the call to generate_signature.

end

let(:secret) { 'secret' }
let(:signature) { 'signature' }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be unused now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed 😄

end

def generate_signature(payload)
signature = Stripe::Webhook::Signature.send(:compute_signature, "#{timestamp}.#{payload}", secret)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shoot. I forgot this is declared private. Sorry about that! I expect this to be pretty stable, but we might want to consider exposing this publicly for testing purposes if nothing else.

@mjc-gh
Copy link
Contributor Author

mjc-gh commented Aug 29, 2017

Refactored the specs some to hopefully make more sense. Thanks again for the feedback!

@coveralls
Copy link

coveralls commented Aug 29, 2017

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 8b53943 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 8b53943 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 8b53943 on mikeycgto:webhook-signature-verification into 7e5ed1e on integrallis:master.

@mjc-gh mjc-gh force-pushed the webhook-signature-verification branch from 8b53943 to 01ffaa8 Compare August 29, 2017 18:50
@coveralls
Copy link

coveralls commented Aug 29, 2017

Coverage Status

Coverage decreased (-0.7%) to 98.571% when pulling 01ffaa8 on mikeycgto:webhook-signature-verification into 6fdee50 on integrallis:master.

@rmm5t
Copy link
Member

rmm5t commented Aug 29, 2017

@mikeycgto Looks good to me. Are you done with your refactoring? I'm happy to merge now when ready.

@mjc-gh
Copy link
Contributor Author

mjc-gh commented Aug 29, 2017

I'm good with merging. Thanks.

@rmm5t rmm5t merged commit 313e531 into integrallis:master Aug 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants