kis.stupid
Posted on October 9, 2023
Did you ever come across the "AllowedHosts": "*"
setting in a server-side .NET project and wondered what it does?
I have. I did my due diligence on the subject, but once in production, I was proven wrong.
What is 'AllowedHosts'?
It is the configuration for the ASP.NET Core host filtering middleware.
With this setting, you can specify one or more host names from which your project allows incoming HTTP requests. Requests without a matching host name will be refused.
A host name is the domain name of the target server, the request is sent to.
Let's say you have an API running on https://www.weather-api.com
. The host name would be weather-api.com
. You could specify to only allow requests with that host name.
{
AllowedHosts: "weather-api.com"
}
Or to allow multiple host names semicolon delimited.
{
AllowedHosts: "weather-api.com;v1.weather-api.com;v2.weather-api.com"
}
Or use a wildcard.
{
AllowedHosts: "*.weather-api.com"
}
The above will allow requests with a correct host name and disallow requests without matching host names.
A host name is set on a request as an HTTP header: Host: weather-api.com
.
Doesn't this sound similar as CORS to you?
What is CORS?
In short, the ASP.NET Core CORS (Cross Origin Resource Sharing) middleware can be configured to allow requests originating from different domains to interact with server-side .NET project.
By default, without this middleware, a server-side project only allows same-origin
requests. These are requests originating from the same domain as the one, the server-side project is running on.
So, the CORS middleware can be configured to enable cross-origin
requests from applications deployed on a different domain. The originating domain name is also set on a request as an HTTP header: Origin: https://www.morning-walk.com
.
The origin header is set to the domain, the request originated from
Allowing requests from the above origin can be configured as follows:
app.UseCors(options =>
options.WithOrigins("https://www.morning-walk.com")
.AllowAnyMethod()
.AllowAnyHeader());
What's the difference?
Requests made by a browser usually sets both the Host
and Origin
headers. Requests made by tools like Postman or by someone running a project locally, will only set the Host
header or none of the above.
When there is no Origin
header present, the CORS middleware will not intervene. The host filtering middleware could intervene and return a 400 Bad Request
when the host name does not match.
Got it! Both middlewares can allow or disallow requests based on their HTTP header. So ... I can protect my API from unwanted origins and unwanted hosts?
Not entirely ... Unfortunately the host filtering middleware cannot be used in the same way as the CORS middleware. The host filtering middleware allows any request as long as the Host
header is correctly pointing to its target server.
Setting "AllowedHosts": "*"
or "AllowedHosts": "weather-api.com"
would not make much of a difference if the goal is to block requests.
Once in production, inspecting the HTTP headers:
Request 1:
Host: weather-api.com
Origin: https://www.morning-walk.com
Request 2:
Host: weather-api.com
Origin: https://kiss-code.com
Do you see how you could block requests based on its origin but not based on the host?
Misconception
I assumed the host name and origin name would come from the same domain, which is wrong. I approached the host filtering in the same way as the CORS configuration. I assumed the values below and tried to filter hosts based on it.
Request 1:
Host: morning-walk.com
Origin: https://www.morning-walk.com
Request 2:
Host: kiss-code.com
Origin: https://kiss-code.com
If you are interested in more of my work, you can find it:
- on my website: kiss-code.com/products
- on my Patreon
- on YouTube
Subscribe to my newsletter to stay up-to-date & receive discounts.
Posted on October 9, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.