2

After researching various webhook implementations, I have noticed a trend in the security mechanisms they use.

Visual Studio Team Services webhooks use Basic Authentication.

Microsoft Graph webhooks sends a plaintext "clientState" in the body of each webhook call. The receiver validates the clientState against a known value. This is similar to Basic Authentication, in that a plaintext credential is sent over the wire with each request.

Slack outgoing webhooks use a very similar technique to Microsoft Graph: a plaintext "token" is sent in the body of each request. The receiver validates the token against a known value. Again, very similar to Basic Authentication: a plaintext credential is sent over the wire with each request.

In all the above examples, the credential never expires. Also, there's only one "token" value per hook, which means there is no way to gracefully rotate a token if it becomes compromised.

My understanding on Basic Auth is that it is generally avoided because it requires the client to store credentials in plaintext, which is a security risk.

Moving on, Github and Box webhooks use shared secrets and signatures for authentication.

The security mechanisms used for webhooks stand in contrast to the security mechanisms used by their respective API - they all use OAuth 2.0 and JWT bearer tokens.

I'm yet to see a webhook implementation that uses token based authentication - e.g., a platform that sends a JWT bearer token in the Authorization header.

My question is: what are the reasons that webhook implementations tend towards less secure mechanisms like Basic Authentication? Why don't they just use OAuth 2.0 and JWT, just like their own API does?

Adrian Hofman
  • 1,421
  • 1
  • 11
  • 24

1 Answers1

1

A token based authentication system does not imply JWT as the token format.

If you pick the Slack or MS Graph implementation and move the clientState/token from the body of the request to an Authorization header using the Bearer scheme you won't find significant differences. It's true that the header would be the most appropriate way to pass information designed to authenticate the request and servers might treat the header in a more secure way than the request body... but for the sake of this discussion lets ignore that.

The token would be a by-reference token where the actual value is meaningless and the validity and any associated information are obtained by the consumer from an independent store. In this case the validity is judged purely by ensuring the token matches the value you expect and there's no additional information stored in association with the token, but this is still an authentication system based on bearer tokens in the sense that anyone that has the token can make the request. Also, the tokens are not obtained through any OAuth 2.0 flow, but that would be overkill for scenarios like these ones.

The Github implementation would be classified as an improvement over the pure bearer one, because there's no token traveling on the wire, only a signature of the payload which means an attacker that is able to decrypt the communication channel would only be able to replay captured requests and not issue requests with different payloads.

Conclusion

You probably won't find webhooks implementations using the full featured OAuth 2.0 plus JWT as the token format, because it would be an overkill for the use case at hand.


Update:

The expiration of a JWT is whatever you want it to be, as it would be the expiration of by-reference tokens (what you call simple tokens).

The message I was trying to pass is that you don't need JWT's, nor OAuth, to have a token based authentication system. The security characteristics of a token based system can be designed independently of the token format used; yes some formats will simplify some aspects while possibly making other aspects more complex. It's always a trade-off...

In a system where you only want to ensure that who's calling is someone you trust and not just a complete stranger a JWT seems overkill; that's my opinion of course.

About the simple token itself being the secret that depends on what you exactly mean by secret. A JWT or a by-reference token used in a bearer authentication scheme gives you the exact same result if they are leaked. Whoever has the token can make request while the token is valid. If you're referring to the secret/key used to sign the JWT which is not transmitted on the wire, again this is something that would be exactly the same if you used a signed by-reference token.

Again, the honest answer to your underlying question is that those system added the security mechanisms they thought were worth it taking in consideration the threat model for the system. Personally, I don't disagree with not using OAuth 2.0 plus JWT as it seems completely not worth it in that use case. My preference would be to go for the Github approach.

You may not like the security characteristics that they provide, but both MS Graph and Slack approaches are token based systems using bearer tokens.

Community
  • 1
  • 1
João Angelo
  • 56,552
  • 12
  • 145
  • 147
  • 1
    I see some significant differences between a jwt and the simple tokens used in these examples: The JWT expires after a short period of time, so if a jwt is stolen its only useful for a short window. Also, the jwt contains no secrets. Otoh, the simple token itself is the secret, and never expires. If its compromised, it remains useful indefinitely, until an admin rotates the token. – Adrian Hofman Nov 09 '16 at 20:51
  • Updated the answer. – João Angelo Nov 09 '16 at 22:04
  • Thanks for the clarification, makes a lot of sense :) – Adrian Hofman Nov 09 '16 at 22:56
  • You mention "an attacker that is able to decrypt the communication channel"; how possible is that decryption over HTTPS? – Kevin Cranmer Aug 16 '21 at 20:43