3

Let us assume that we have a public API, for example, company.com/publicEndpoint, that can accept requests from any source. Various websites, like foo.com and bar.com, use JavaScripts that call this endpoint to retrieve a list of strings, among other things.

Is there a secure way for company.com/publicEndpoint to ensure that only requests from foo.com or bar.com (and not from zzz.com) are allowed (of course only via browser)? We could use referer or origin, but these HTTP headers can be easily overwritten or modified. I am searching for an approach that allows us to "fingerprint" the request so that it is almost impossible to fake a request coming from foo.com or bar.com.

Is it feasible to achieve this using only the frontend, without implementing a token system with a backend on foo.com or bar.com?

5
  • 1
    What is your threat model? Someone creating a fake webpage fetching data from you, with unsuspecting users browsing it? If so, you can trust headers, as the browser is not the attacker, and CORS should be able to stop it.
    – vidarlo
    Commented Mar 7, 2023 at 17:21
  • @vidarlo the CORS would prevent the case you are refering to, but imagine a case where another website creates a backend and acts as a proxy by altering the HTTP headers and sending the request with altered referer and origin. Then CORS wouldn't be enough Commented Mar 7, 2023 at 17:30
  • @MichelGokanKhan No, that's why I'm asking for clarification of the threat model.
    – vidarlo
    Commented Mar 7, 2023 at 17:45
  • You can whitelist certain IPs, and have those IPs make the calls, (it would no longer be a public endpoint)... so any user could access your whitelisted IP, and it's server would call your API and pass along the data retrieved to the client. (You could also use certs or API keys that you deliver to the other servers to authenticate them.) This would also have the benefit of keeping all the calls same domain, which is ideal for security. Commented Mar 7, 2023 at 18:16
  • it's like you describe by default, there's no need to even check headers to protect from browser traffic, unless you use CORS.
    – dandavis
    Commented Mar 8, 2023 at 6:35

1 Answer 1

5

We could use referer or origin, but these HTTP headers can be easily overwritten or modified.

A browser can not overwrite or modify these headers. At most it can make the referer blank or reduce to domain instead of full path - but not change it to a different domain. If you just want to make sure that other sites don't use your API via a normal browser, then checking the origin of the request or restricting access with CORS is thus sufficient.

It is not sufficient though if you fear that non-browser clients (like information scraping bots) might misuse the API. Many content delivery networks or web application firewalls provide more or less reliable and maintained heuristics to block access from such bots. These heuristics are based on context, ability to execute script, TLS fingerprint of the client etc. They are not foolproof though, so they don't protect against a determined attacker.

If the requests to the API in your setup are not expected from the browser but instead from the third party backend, then your only way to distinguish valid from unwanted requests is to have some kind of authentication, like client specific authentications tokens, client certificates or similar.

7
  • A browser can't overwrite or modify these headers, true, but a backend application can alter referer or origin and set it to foo.com, and after fetching the data it can provide it to the frontend in zzz.com, so that zzz.com can actually pretend it's reading from foo.com Commented Mar 7, 2023 at 17:32
  • @MichelGokanKhan: If a valid request is expected from a browser is addressed by the first two parts. I've added a third part were the valid request is not expected from the browser. Not sure if your comment refers to this case. Commented Mar 7, 2023 at 18:05
  • Thanks, my point was that if someone really wants to attempt faking the referrer or origin, they can do it by making a simple backend and fetch the data from foo.com, and pass it on to frontend of zzz.com. Perhaps, as you kind of suggested, adding a rate limiter or some kind of firewall would prevent such cases and automatically find and block IP of backends who try to do that ... I can imagine it might be possible to detect (not sure how yet, except for rate limiting...) Commented Mar 7, 2023 at 20:05
  • @MichelGokanKhan: sure, one could also use a modified browser to do this. From my understanding though the question is more about a site abusing the API by embedding it in their own page served to the innocent users browser and not about the user itself abusing the API. Commented Mar 7, 2023 at 20:09
  • I know, but a site who wants to abuse the API don't have to directly embed or call that API, it can create a fake backend that calls that API with modified referer or origin and then that backend provide the response to frontend. So the frontend only use the responses of that backend (that could modify the header and abuse the API) Commented Mar 7, 2023 at 20:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .