Misconception about 'AllowedHosts' in a .NET C# Web API
Tags: dotnet, csharp, api, webdev
Published: 2023-10-09 18:46:24

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.

``` json
{
    AllowedHosts: "weather-api.com"
}
```

Or to allow multiple host names **semicolon** delimited.

``` json
{
    AllowedHosts: "weather-api.com;v1.weather-api.com;v2.weather-api.com"
}
```

Or use a wildcard.

``` json
{
    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:

``` csharp

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](https://www.kiss-code.com/products)
- on my [Patreon](https://www.patreon.com/kisstupid)
- on [YouTube](https://www.youtube.com/@kis.stupid)

Subscribe to my [newsletter](https://www.kiss-code.com) to stay up-to-date & receive discounts.