Sharing the secret key for HMAC based authentication for webhooks - webhooks

I have just started implementing a webhook provider, where clients can register by providing their webhook address.
Most of the concepts are clear to me, and as I understood from various sources - we need to implement an HMAC based authentication to validate the authenticity and integrity of the message.
What is not clear to me though is, when and how can we share the secret that we need to use to sign the request (and eventually the client to verify the signature) with the clients? Do we share it as a response when they create the webhook - are there any recommended ways? This part is not very well defined anywhere.

Related

Stable and reliable OAuth client proof

In OAuth, client_id and client_secret are enough to prove that you are a client. I think that's not enough, so I thought about adding a client's authority check (e.g. if his domain matches the one stored in the server's database), but the Origin header can be forged by anyone. Is there anything on which the client's authority can be reliably based? I have one idea, but it seems weak because in this idea the server has to send a request to the client to confirm that he sent the request and not someone else. In other words, is it possible to uniquely identify the source of the http request?
There are two stronger forms of the OAuth client secret, where proof of ownership of a cryptographic private key is sent:
Client certificates
Client assertions
Both of these do not reveal secrets in HTTP messages. They are standard solutions and pretty widely used.
The first option tends to require an extra token endpoint that requires Mutual TLS, whereas the second can be easier to manage.

Automated client secret

I want to implement the Google calendar in my application. So as a developer I go to the console download my secret.json and can now access the data. But as a customer you don't have to deal with all of that you just see the OAuth Screen and then you can login. So how do I get from I have to download the secret manually to just login.
The concepts are different. One important note is that the client means the client application. The user uses an application, which is client of an Identity Provider (in your case, Google, right?).
The user login is the way that the user tells the Identity Provider who he is. This is typically done using the Authorization Code Flow.
The secret (client secret), when used, must be known solely by the client application and the Identity Provider (auth server). In this way, when the application performs a request to the server, the secret helps to prove the authenticity of the request. Sometimes, a secret is required, but not always, and it may be optional.
So, the client secret may be employed in different scenarios, such as the mentioned Authorization Code Flow or commonly in machine-to-machine flows (e.g. the Client Credentials Flow).
Perhaps, you are implementing something like Google docs describe here. You can probably use an Authorization Code Flow, with your app sending the secret to Google Identity Server (however, the user does not know this).

How to securely pass the API Key in the HTTP Header?

I am building a API suite to connect to our application. Each user will have an unique API key which will be passed in the Header.
I am here to ask, what is the best way to authenticate the user? I donot want the user to pass the API key without any encryption ?
I am passing the API key like this :
$headers['x-axpr-auth'] = '<API-KEY>';
Since, I am building the API myself, I have the flexibility to use different encryption/authentication techniques.
Using HTTPS is pretty much mandatory in this case so I'm going to assume you (will) do that.
If you have an API key with long-term validity, then you should consider using some kind of "temporary token" with (very?) limited validity - so the attack window is much smaller.
This is similar to using Basic Authentication (sending password with every request) versus sending credentials only once and using session cookie afterward.
You should look at existing authentication/authorization schemes - OAuth2 (with access and refresh tokens) may be relevant since you're building APIs. OpenID Connect builds on top of OAuth2 and provides a proper authentication layer.
Apart from that, it's uncommon to explicitly encrypt API token in an HTTP header, since the whole communication is already encrypted using HTTPS.

HTTPS or JWT for authentication?

I'm going to implement my authentication method using JWTs in node js.
I was searching a while for different methods of authentication and finally decide to use JWTs.
However I am confused about the JWT based authentication.
Here's my question : Should we send our JWT over HTTPS? if yes, then why should we use JWT at all ? and why not sending all needed information over HTTPS without JWT ?
In other words when there is security issues without HTTPS (like man-in-the-middle attack), what is the reason of using JWT for authentication purposes? is there any other authentication approach which works perfectly without using HTTPS?
Here you are mixing two different protocol levels.
HTTPS (or rather TLS - transport level security) is a transport layer - data transport pipe ensuring you communicate with a legitimate server and that nobody could read or change the data exchanged. HTTPS doesn't care about data itself (e. g. authentication)
JWT is commonly used as part of the payload (data itself) describing client's identity and other attributes.
Most commonly you need both - JWT to ensure authentication or authorization and TLS/HTTPS to ensure that nobody could steal or change your JWT token or data.
HTTPS could provide client authentication, but the client needs to have its client keypair and certificate which is not really free or easy to manage (e. g. this is how electronic ID cards work or I see it often in the server-to-server scenarios).
To expand on #gusto2
JWT and HTTPS accomplish different goals. Three major components of security systems.
C - Confidentiality - Is data secure from outsiders reading it?
I - Integrity - Is data secure from outsiders tampering with it?
A - Authenticity - Is data sent from the proper person
HTTPS ensures confidentiality and integrity.
JWT helps with authenticity. However, it is your job to ensure that tokens
are valid. This is not provided out of the box.
“and why not sending all needed information over HTTPS without JWT ?”
I think the main point is that Restful or API based interaction is stateless. So in all interaction server needs to get the token to know the authenticity. And for authenticity that all requests are coming from logged in authentic user it needs to get same JWT.
Hence answer to the question in OP as Daniel said is for Authenticity.
In normal form based request we do not use token, why? Because it is stateful and we save information in session or cookies. But APIs are stateless so some token needs to be sent.

How to secure webhook identity

I am developing a service where customer can register their webhook URL and I will be sending updates on the registered URLs. For the sake of security, I want to let the client (receiver) identify that its me(server) who is sending them the request.
Facebook and Github both sends a X-Hub-Signature containing the hash of the payload prefixed with a secret key.
I can follow the same strategy. But what if I simply use jwt:
On registering the webhook I share a secret key with the client.
Then in each webhook request I will be sending a jwt computed using the same secret key.
I don't know much about cryptography, but the jwt approach seems more efficient as I don't have to compute the signature again and again because I am not using the payload in the signature.
But then why both Facebook and GitHub follow the other approach?
The content on this site may be out of date. For the most accurate and up-to-date content, visit
Using a MAC (Message Authentication Code) allows one to authenticate a message, as implied by the name. Sending a secret with every message is not wise, as this is likely to result in the secret being compromised. An attacker might intercept one of the messages and then start issuing spoofed messages.
Another thing which you might want to consider is replay attacks. What if an attacker intercepts a message and sends the same message later?
Edit: Using JWT is fine, as it includes a MAC, but you must make sure that the payload is authenticated (i.e. included in the computation of the MAC).

Resources