7

I have a REST API that can potentially serve multiple web clients.

I want to ensure that only my single page app on my-one-and-only-web-cleint.com can make requests to my API. How do I do this?

Right now there isn't much to stop someone from copying the source of my website and act as a copy of my single page app on my-one-and-only-web-cleint.com.

Only check I have right now is:

  • On server side: I check for request header's origin and only allow requests from my-one-and-only-web-cleint.com

But my understanding is that you can manually change the header, so this check can be bypassed.

garbage collection
  • 173
  • 1
  • 1
  • 5

2 Answers2

5

This sounds like preventing a CSRF attack. The Same Origin Policy will already prevent anything within your API from being read by another domain, but to prevent requests that makes changes to your system you will need to guard against CSRF.

On server side: I check for request header's origin and only allow requests from my-one-and-only-web-cleint.com

Checking the Origin header or a custom one such as X-Requested-With is a valid way to beat CSRF.

An attacker cannot forge this header in the web browser, so anyone connecting to the attacker's site which he has connected to your API will not be able to use it as their browser header cannot be tampered with.

You should also rely on an authorisation system to prevent the attacker from making API requests server side (where they can set any header they want).

andras
  • 103
  • 2
SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Thank you. What authorization system can I be using for this purpose? – garbage collection Jul 27 '14 at 18:35
  • @gar by that I meant protect your app by a user name and password for each user of your system . – SilverlightFox Jul 27 '14 at 18:40
  • @SilverlightFox - I think the CSRF token would just ensure that other tabs not pointing to his app(so not using his client) can't make the request. But I can imagine that a authenticated user could get a CSRF token and then use it in a malicious client(for what reasons, that's another question) to make requests. – Nick Pineda May 07 '16 at 06:47
  • 1
    @nick Yes, that's true. However, with authentication you will then know the accounts which are doing this to throttle or block them, either automatically based on a request limit, or manually. – SilverlightFox May 07 '16 at 12:09
  • @SilverlightFox - I've seen a lot of your posts on S.O. You are the man at security! ;) – Nick Pineda May 07 '16 at 19:13
  • I don't see how this is supposed to help. Just use curl, extract the token, build a new request with it and fake the headers for the final curl request. It's an obstacle but no real protection. – tcurdt Jan 24 '20 at 16:58
  • @tcu CSRF is a client-side attack against other users. The browser sending the request is that of the victim, not the attacker. Therefore curl won't help here, as the victim would be the one that would have to be running it. CSRF is where the attacker's malicious site sends a request to a legitimate site when the victim visits the malicious site and then sends the victim's cookies with it. Adding a header that can't be sent cross domain by a browser mitigates this. – SilverlightFox Jan 25 '20 at 06:35
  • 1
    @SilverlightFox But the question was "How to ensure only my SPA can access the API". I don't see how SOP or a CSRF token ensures I cannot connect to the API outside of a browser. – tcurdt Jan 25 '20 at 19:02
  • @tcu Well the answer has been accepted, so this indicates that it is likely to be what the OP asked. To answer your question, nothing can really stop someone using curl or a reverse proxy from using an internet exposed API when this API is accessed client-side from a web browser. The best bet is to supply unique API keys and then monitor for excessive or 'unusual' use of your API. – SilverlightFox Jan 26 '20 at 07:38
  • @tcu Actually, reading my answer back my last paragraph touches on this. If, for any application functionality, a user had to be authenticated, then on the backend you monitor these accounts for usage, and any accounts with excessive use could be being used by a 3rd party front-end. More of an heuristical approach of detect then disable rather than blocking it entirely. – SilverlightFox Jan 26 '20 at 07:48
2

It sounds like a situation similar to CSRF attacks, so it should be addressable with anti-forgery tokens.

Anti-forgery tokens should achieve what you need. Each time you get a web request, you serve an anti-forgery token to the client as part of the FORM or script or webapp. The token embeds values like a date, login id, and client ip, encrypted with a secret key only known to your server. Then you only handle requests that include valid tokens.

A middle man can't modify your site and host its API on theirs, because they won't be able to serve valid tokens.

Here's more info on how to do this in ASP.NET, but the same applies in other languages.

http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/