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:

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.