libesphttpd
libesphttpd copied to clipboard
Fix security issue when url starts from multiple slashes.
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.
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.
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.
Yes I'm actually don't see the reason to "strip all except one" but variant is acceptable I guess.
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.
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);
}