Spritetm / libesphttpd

NOTE: THIS CODE IS UNMAINTAINED. Please take a look at https://github.com/chmorgan/libesphttpd instead.
125 stars 109 forks source link

Fix security issue when url starts from multiple slashes. #44

Open valkuc opened 6 years ago

chmorgan commented 6 years ago

Hi @valkuc. Appreciate the patch very much! If you've been watching there are a ton of improvements to this fork of the repository and even more due to cooperation with another fork.

For the authentication check does that require the leading slashes to work correctly and that is why removing them breaks going through the authentication check? I'm not sure I'm familiar with the authentication path.

valkuc commented 6 years ago

Suppose you have a next URL mappings:

{"/private/*", authBasic, cgi_private_area_auth_handler},
{"/private/secure.html", cgiEspFsTemplate, cgi_secure_tpl}

Navigating to /private/secure.html will prompt user to enter credentials. This can be "hacked" by entering url with extra slash appended. Without this patch accessing URL by //private/secure.html (note the extra slash at beginning) will skip authentication handler.

chmorgan commented 6 years ago

It skips the handler because it isn't an exact match for the authentication handler but is a match for the url handler?

Would it make sense to strip all but one leading '/'? The original implementation seems to remove them all.

valkuc commented 6 years ago

Yes I'm actually don't see the reason to "strip all except one" but variant is acceptable I guess.

chmorgan commented 6 years ago

It's interesting that stripping all of the slashes results in an authentication issue. In any case I trust your testing and will apply the changes.

valkuc commented 6 years ago

I have thinking of why this happens, but now don't remember. I have found this issue 4-5 months ago and now decided to create a pull request with it. You can check it, the setup is quite simple. Here is a code snippet for auth handler:

int ICACHE_FLASH_ATTR cgi_private_area_auth_handler(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen)
{
    if (no == 0)
    {
        os_strcpy(user, PRIV_AREA_USERNAME);
        os_strcpy(pass, PRIV_AREA_PASSWORD);

        return 1;
    }

    return 0;
}

And handler for espfs page:

void ICACHE_FLASH_ATTR cgi_secure_tpl(HttpdConnData *connData, char *token, void **arg)
{
    if (token == NULL) return;

    char buf[8];
    os_strcpy(buf, "test");
    httpdSend(connData, buf, -1);
}