Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate User In Third Party Invoked WebHook

I have a setup in which

  1. the user may or may not log on to my site,
  2. the user submits a form to a 3rd party service, and
  3. the 3rd party service does its thing, then invokes a "webhook" on my site, forwarding all $_POST data.

So, to illustrate:

    +---------------------+         +---------------------------+
    | mysite.com/form.php |-------->| thirdparty.com/submit.php |
    +---------------------+         +---------------------------+
                                                  |
                                                  v
                                    +---------------------------+
                                    |   mysite.com/webhook.php  |
                                    +---------------------------+

If the user was logged on at the time of submitting the form, then how can I tell and authenticate this fact in the webhook?

For example, I could naively set a hidden field,

<input type="hidden" name="loggedOn" value="true" />

But anyone can spoof that. I thought I might pass through the user's password hash,

<input type="hidden" name="passwordHash" value="$2a$08$Lg5XF1Tt.X5TGyfb43vBBeEFZm4GTXQhKQ6SY6emkcnhAGT8KfxFS" />

Effectively making the webhook "log in" again, but this can't be correct, as it would expose the user's password hash to the client-side.

I think there must be a better way to do this using session mechanics but I'm new to sessions. Perhaps I'm missing the appropriate vocabulary? Would someone guide me in the right direction? Thanks!


EDIT:

After further research I believe the correct method is to set a hidden form field sid to the session id, session_id(), in order to pass it to the webhook, which in turn will use the session id to continue the session, session_id($_POST['sid']); session_start();. My question is now whether this is the canonical (and secure) solution.

like image 459
slackwing Avatar asked Feb 15 '26 07:02

slackwing


2 Answers

A user's SessionID is known to the user anyway, and can be sniffed by man-in-the-middle approaches anyway. So if you're concerned that security can get "hacked" (and you can't go to SSL) then you would implement IP tracking, agent tracking etc. All details that can be spoofed or faked, and may even change mis-session (albeit rarely, except IP's on mobile) but it's an extra layer to add.

So the basic solution will be for you to create a session_id, pass as part of the form and then use it as you/Steve propose.

You can't use IP or Agent headers as these are lost. So you need to look at what you can use.

In increasing order of complexity, but security:

  1. Does the thirdparty.com for pass on any data to you, other that the post? Check the headers; you may find they pass originiating IP, originating referrer or agent. You could use those as the simplest line of defence - they should match the original data (that you can store in a session).

  2. When you create the form on your site, create another Unique ID and store in the session. Pass that in a hidden field as well to the form, when you get back the form data from "thirdparty.com" you can check the unique ID matches that on the session. Then remove the uniqueID from the session, meaning it can only be used once. (This is the NONCE pd40 refers to in his answer.)

  3. If you can use javascript then trap the on submit, also send the details to your server. Your server will already have the details in the session. When "thirdparty.com" comes back to you, call up the session and check the details match. (If you don't want to store all the details in the session, you could MD5 it - the MD5 should match on return). You can also timestamp this - if you don;t hear back within 60 seconds then something's goen a bit slow [adjust timestamp to your needs, but be generous].

  4. However, my preferred (and the one we use) is to have your own server receive the form data, then generate the POST request to thirdparty.com using Curl. No actual need for the webhook - you just check the response before continuing processing yourself - the user never realises a third party is invovled and the interaction is between yourself and the server.

Also, if you're really worried, log any calls you consider "invalid". You'll find that users try to hack things a few times before they get it right - so NEVER reveal that you've identified them as a hacker (unless there's a chance of a false-positive; so be careful on this) and log. If you get 5 invalid requests from one IP (for example) then you can assume all subsequent requests from that IP are dodgy, even if good. Keep a log so you cna monitor.

Final note: SSL is always best, if you can implement it.

Hopefully that gives you an idea of the options you can implement.

like image 139
Robbie Avatar answered Feb 17 '26 19:02

Robbie


Using session ID is good for keeping track of who made requests and provide some security protection.

You could also consider making each request to the third party contain:

  • A nonce to detect replay
  • Timestamp to detect old requests
  • A digital-signature or hmac sent with each request. You would sign/hash any values that might be tampered with and verify these values in the webhook
like image 33
pd40 Avatar answered Feb 17 '26 21:02

pd40



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!