0

I have a both a http and websocket server written in nodejs (for now) and it will be receiving requests from many different domains. The request is made from the client using JS.

I need to verify 100% that the request is from that originating domain. When I receive the request I want to verify the third party domain from which it originated - to ensure someone is not submitting requests pretending to be another domain.

I can give each domain an identity, but the request is originating from the client side.

I am using HTTPS on my domain.

Let say I am running a server at A.com and I allow people to download my JS client-side SDK and make requests to my server. When I receive a request from B.com I need to ensure this is where the client actually is.

Is SSL / HTTPS enough? Should I assume that when my server receives a request from an SSL enabled site I can 99.999% trust the URL in the header?

  • Could you provide some more context? Are requests done using JavaScript from a webpage on another domain? Are you using HTTPS on your own domain? You ask if you can trust the URL in the header, which header do you mean? – Sjoerd Oct 30 '18 at 14:32
  • 1
    It almost sounds like you're trying to ensure that only customers running the javascript you supply are executing it when they are on one of the domains you've allowed. Is that correct? In this case you could do this by having those domains make a request to your server each time, to generate a token. They would embed that one-time-use token in the javascript for that singular page render, and you would associate that token with the domain, and only accept requests using that token once (and also time it out after a cretin limit). – Daisetsu Nov 5 '18 at 3:22
1

I'm not entirely sure what you mean by this

When I receive the request I want to verify the third party domain from which it originated - to ensure someone is not submitting requests pretending to be another domain.

For example, here's the HTTP request that my browser made to load this page:

GET /questions/196706/verify-the-requesting-domain HTTP/1.1
Host: security.stackexchange.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 
Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: ... snip ....
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

Nothing in there indicates which domain my web browser is coming from. I'm not even sure I know what that means.

Maybe you mean that your API will be accessed from pages served from other domains and you want to mine the Referrer: header?

Referer: https://my.domain.com/somepage

Either way, the client-server architecture of HTTP means that there is no security here; the client can literally put whatever it wants in the request and the server has no way to verify if it's "correct". Whether it's using HTTP or HTTPS makes no difference here.

Consider the following cURL command which shows that I can craft an HTTP request with any header text I want, and then send it to any server I want:

curl -X GET -H "Accept: text/html" -H "Referer: https://my.domain.com/somepage" https://someHostName/someEndpoint

Solution: Mutual-auth (aka "client auth") TLS

It sounds like the solution you're looking for is mutually-authenticated TLS, which is designed precisely to force the client to prove its identity before the server will open a connection.

This would involve issuing certificates to your clients (just like you do with your server), and then configuring your server to only accept incoming connections from trusted certificates.

  • Hello Mike, sorry that I have not been clear. Let say I am running a server ad A.com and I allow people to download my JS client side SDK and make requests to my server. When I receive a request from B.com I need to ensure this is where the user/browser actually is. – dendog Oct 30 '18 at 15:22
  • I think my answer still holds: you can mine the Referrer: header (or some other header) which will tell you where honest clients came from, but there's nothing stopping an attacker with a command-line from sending requests to your server with whatever header text they want. – Mike Ounsworth Oct 30 '18 at 15:31
  • Thank you Mike, but does SSL / HTTPS not prove anything about the origin of the request? – dendog Oct 30 '18 at 16:15
  • The default mode of HTTPS / TLS ("SSL" was deprecated in 1999) is Server Authentication -- ie only the identity of the server is verified. If you want Mutual Authentication -- ie the identity of both parties are verified -- then you need to do the client certificate thing. TLS is about opening a TCP connection and has nothing to do with the text in an HTTP header. You could also solving the problem with a Single-Sign-On (SSO) service using SAML or OpenID Connect which will tell you which end-user on B.com the request is coming from. – Mike Ounsworth Oct 30 '18 at 16:24
  • 2
    @ydennis keep in mind that if the client is javascript running in a browser then client-side authentication is pretty much ruled out. It would be too easy for an attacker to steal the key from the browser and, once again, spoof requests from elsewhere. It's not impossible but browsers are literally just not designed for this, so doing it well can be difficult – Conor Mancone Oct 30 '18 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.