3

If I release an API on the public internet, but it's only meant to be used by my apps, I can make a white list of accepted domains, so other domains can't use it.

But I always wonder, can't hackers edit their "from domain" when making an HTTP request to my APIs? Can't they mimic some other domain to trick my API that they're trusted?

AskYous
  • 4,332
  • 9
  • 46
  • 82

2 Answers2

6

The Origin Http Header

But I always wonder, can't hackers edit their "from domain" when making an HTTP request to my APIs?

You are referring to the Origin that according to the Fetch Standard should not be present in all requests:

3. HTTP extensions
3.1. `Origin` header

The `Origin` request header indicates where a fetch originates from.

The `Origin` header is a version of the `Referer` [sic] header that does not reveal a path. 
It is used for all HTTP fetches whose request’s response tainting is "cors", as well as those where request’s method is neither `GET` nor `HEAD`. 
Due to compatibility constraints it is not included in all fetches. 

Let's test it:

$ curl http://httpbin.org/headers 
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.58.0", 
    "X-Amzn-Trace-Id": "Root=1-5e907f49-3b96ed48ef957ff4c8aa435e"
  }
}

As you can see cURL implements properly the RFC and doesn't send the Origin header for the GET request.

So even if an attacker was not able to spoof it, as they can trivially do, you could not rely on it because any Browser that would properly implement the RFC would be blacklisted by your API, unless your API was only accessed by non Browser clients that always implement the Origin header, no matter what http method.

Faking the Origin Header

Can't they mimic some other domain to trick my API that they're trusted?

An attacker can just see how your genuine app does the requests and replay it with the correct Origin header:

$ curl http://httpbin.org/headers -H "Origin: your-genuine.domain.com"
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "Origin": "your-genuine.domain.com", 
    "User-Agent": "curl/7.58.0", 
    "X-Amzn-Trace-Id": "Root=1-5e907f9a-4696e1c9ec807a0defdeca54"
  }
}

See how easy is to replay a request with the genuine domain for your app ;). You can read more about replay attacks in this other answer I gave for the question How to secure REST API from replay attacks with parameter manipulation?.

So trying to defend your API based on the Origin header is not feasible, because in first place RFC doesn't allow it to be sent in all request methods, second is very trivial to fake it.

Defending the API Server

If I release an API on the public internet, but it's only meant to be used by my apps, I can make a white list of accepted domains, so other domains can't use it.

As already demonstrated above, relying on the domain doing the request isn't feasible.

So now you may wonder how you can defend your API server from being used by unauthorized clients?

The approach will depend on what your API server is supposed to server, only web apps, only mobile apps, both, and maybe even IOT clients?

In order for you to understand how you can start applying layers of defence, you need to first understand the difference between who vs what is accessing your API server. You can go and read this article section to find this statements:

The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?

The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

If the above two sentences are not clear enough, than go and spend some seconds to read the entire section in the linked article.

Now that you understand the difference between who and what is accessing your API server you start applying as many layers of defenses as you can afford and are required by law.

For an API serving only a mobile app you will want to end up in this type of architecture:

Mobile App Attestation

Yes, no API keys or any other type of secrets stored in the mobile app, and you can read more about in this other answer I gave for the question How to secure an API REST for mobile app? (if sniffing requests gives you the “key”), that explains the graphic in more detail.

For a Web app you may be already covered if you alread have read the previous link for the replay attacks answer, but if not, here it is again the link I gave for the question How to secure REST API from replay attacks with parameter manipulation?. This answer as code examples of using HMAC to sign the requests sent to the API server.

GOING THE EXTRA MILE

I cannot finish a security answer without my usual recommendation to visit the excellent work of the OWASP foundation:

The Web Security Testing Guide:

The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.

The Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

Community
  • 1
  • 1
Exadra37
  • 11,244
  • 3
  • 43
  • 57
1

Not every HTTP request specifies its domain, so at best you can try to map the source IP to a domain.

If your accepted domains has constant IP ranges, you can whitelist those and block everything else.

IP spoofing is generally possible if the attacker has an insider in the networking layer leading to your host site. Without it, attackers can try and DoS your APIs, but it would take a lot of work for them to send HTTP requests.

If you use HTTP headers to declare a domain, then attackers can absolutely spoof them.

If your APIs only serve your application, the simplest solution is to use HTTPS and sign and/or authenticate every request (look into JWT, it's very popular these days).

There are also solutions based on identifying "unexpected" requests, which also don't require your apps to have constant IP ranges, and also are safer to open your APIs to apps you don't own. Those are Web Application Firewall (WAF) solutions, some have free tiers.

The key thing to remember is that there is a large number of "basic" hackers and a small number of "master" hackers, and security is all about weeding as many hackers from the lower layers of this pyramid. A strong, resourceful, well-funded attacker will eventually hack you, but more often, you just want the attackers looking to make money to go attack an easier target.

root
  • 5,528
  • 1
  • 7
  • 15
  • Thanks! Can hackers spoof IP addresses then? Also, what's the alternative if I shouldn't read from HTTP headers? – AskYous Oct 13 '19 at 03:51
  • HTTP runs on TCP, TCP IP spoofing is very very hard to do if not impossible – Raymond Nijland Oct 13 '19 at 15:34
  • plus it requires something [else](https://security.stackexchange.com/a/37482/84973) to work.. As you also need to prevent the attacking host sending the host which IP you try the spoof the TCP "reply" instead ... Thats why i said TCP IP spoofing is very very hard to do if not impossible as most likely you can't easy control the path where the packets travel on the internet unless you hack a router in there own network or IP Source Routing is enabled .. – Raymond Nijland Oct 14 '19 at 12:12
  • ... also after a review i also would not trust JWT securitywise atleast not with SHA256 signing -> `HMAC-SHA256(base64urlEncoding(header) + '.' + base64urlEncoding(payload), secret )`. SHA256 is a fast algorithm milions of hashes per second can be bruteforced on medium GPU's to find that`secret` when the hacker finds that he can use any account. Well sha256 might be "safe" when adding atleast 40 - 50 good randomly (utf8) chars off salt. But JWT would be much safer when you use something like bcrypt/blowfish https://en.wikipedia.org/wiki/Blowfish_(cipher) as Signature or use RSA offcource.. – Raymond Nijland Oct 14 '19 at 12:30