From ef0e4288350b3769cbf7e209747e2d62f9107d75 Mon Sep 17 00:00:00 2001 From: valkuc Date: Wed, 11 Oct 2017 13:52:31 +0300 Subject: [PATCH 1/2] Fix security issue when url starts from multiple slashes. --- espfs/espfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/espfs/espfs.c b/espfs/espfs.c index e179cb95..919373ef 100644 --- a/espfs/espfs.c +++ b/espfs/espfs.c @@ -135,8 +135,9 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { char namebuf[256]; EspFsHeader h; EspFsFile *r; - //Strip initial slashes - while(fileName[0]=='/') fileName++; + //Strip first initial slash + //We should not strip any next slashes otherwise there is potential security risk when mapped authentication handler will not invoke (ex. ///security.html) + if(fileName[0]=='/') fileName++; //Go find that file! while(1) { hpos=p; From 70a68d6345752cabe739da28c8ee11d54bb525a0 Mon Sep 17 00:00:00 2001 From: valkuc Date: Wed, 18 Oct 2017 17:34:26 +0300 Subject: [PATCH 2/2] Hostname and HTTP 1.1 header names are case insensitive according to specs --- core/httpd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/httpd.c b/core/httpd.c index 4d0b63c6..1f4f437e 100644 --- a/core/httpd.c +++ b/core/httpd.c @@ -194,7 +194,7 @@ int ICACHE_FLASH_ATTR httpdGetHeader(HttpdConnData *conn, char *header, char *re while (p<(conn->priv->head+conn->priv->headPos)) { while(*p<=32 && *p!=0) p++; //skip crap at start //See if this is the header - if (strncmp(p, header, strlen(header))==0 && p[strlen(header)]==':') { + if (strncasecmp(p, header, strlen(header))==0 && p[strlen(header)]==':') { //Skip 'key:' bit of header line p=p+strlen(header)+1; //Skip past spaces after the colon @@ -311,7 +311,7 @@ int ICACHE_FLASH_ATTR cgiRedirectToHostname(HttpdConnData *connData) { } if (isIP) return HTTPD_CGI_NOTFOUND; //Check hostname; pass on if the same - if (strcmp(connData->hostName, (char*)connData->cgiArg)==0) return HTTPD_CGI_NOTFOUND; + if (strcasecmp(connData->hostName, (char*)connData->cgiArg)==0) return HTTPD_CGI_NOTFOUND; //Not the same. Redirect to real hostname. buff=malloc(strlen((char*)connData->cgiArg)+sizeof(hostFmt)); if (buff==NULL) { @@ -581,7 +581,7 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { if (strncmp(h, "GET ", 4)==0) { conn->requestType = HTTPD_METHOD_GET; firstLine=1; - } else if (strncmp(h, "Host:", 5)==0) { + } else if (strncasecmp(h, "Host:", 5)==0) { i=5; while (h[i]==' ') i++; conn->hostName=&h[i]; @@ -617,12 +617,12 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { } else { conn->getArgs=NULL; } - } else if (strncmp(h, "Connection:", 11)==0) { + } else if (strncasecmp(h, "Connection:", 11)==0) { i=11; //Skip trailing spaces while (h[i]==' ') i++; if (strncmp(&h[i], "close", 5)==0) conn->priv->flags&=~HFL_CHUNKED; //Don't use chunked conn - } else if (strncmp(h, "Content-Length:", 15)==0) { + } else if (strncasecmp(h, "Content-Length:", 15)==0) { i=15; //Skip trailing spaces while (h[i]==' ') i++; @@ -643,7 +643,7 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { return; } conn->post->buffLen=0; - } else if (strncmp(h, "Content-Type: ", 14)==0) { + } else if (strncasecmp(h, "Content-Type: ", 14)==0) { if (strstr(h, "multipart/form-data")) { // It's multipart form data so let's pull out the boundary for future use char *b;