mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 02:59:01 +08:00
Stricter realpath checks
This commit is contained in:
parent
ae5f6c0920
commit
d5a1d5a5e8
15
mongoose.c
15
mongoose.c
@ -1090,11 +1090,11 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
char t1[MG_PATH_MAX], t2[sizeof(t1)];
|
||||
t1[0] = t2[0] = '\0';
|
||||
|
||||
if (realpath(opts->root_dir, t1) == NULL)
|
||||
if (realpath(opts->root_dir, t1) == NULL) {
|
||||
LOG(LL_ERROR, ("realpath(%s): %d", opts->root_dir, errno));
|
||||
|
||||
if (!mg_is_dir(t1)) {
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", t1);
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", opts->root_dir);
|
||||
} else if (!mg_is_dir(t1)) {
|
||||
mg_http_reply(c, 400, "", "Invalid web root [%s]\n", t1);
|
||||
} else {
|
||||
// NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for
|
||||
// the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
|
||||
@ -1106,8 +1106,11 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
n2 = strlen(t1);
|
||||
while (n2 > 0 && t1[n2 - 1] == '/') t1[--n2] = 0;
|
||||
|
||||
if (realpath(t1, t2) == NULL)
|
||||
if (realpath(t1, t2) == NULL) {
|
||||
LOG(LL_ERROR, ("realpath(%s): %d", t1, errno));
|
||||
mg_http_reply(c, 400, "", "Error serving [%s]\n", t1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mg_is_dir(t2)) {
|
||||
strncat(t2, "/index.html", sizeof(t2) - strlen(t2) - 1);
|
||||
@ -1117,7 +1120,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
|
||||
if (strlen(t2) < n1 || memcmp(t1, t2, n1) != 0) {
|
||||
// Requested file is located outside root directory, fail
|
||||
mg_http_reply(c, 404, "", "Not found %.*s\n", (int) hm->uri.len,
|
||||
mg_http_reply(c, 404, "", "Invalid URI [%.*s]\n", (int) hm->uri.len,
|
||||
hm->uri.ptr);
|
||||
} else {
|
||||
FILE *fp = mg_fopen(t2, "r");
|
||||
|
@ -270,7 +270,7 @@ typedef int socklen_t;
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#endif
|
||||
#define realpath(a, b) _fullpath((b), (a), 512)
|
||||
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||
#ifndef va_copy
|
||||
#ifdef __va_copy
|
||||
#define va_copy __va_copy
|
||||
|
@ -40,7 +40,7 @@ typedef int socklen_t;
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#endif
|
||||
#define realpath(a, b) _fullpath((b), (a), 512)
|
||||
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||
#ifndef va_copy
|
||||
#ifdef __va_copy
|
||||
#define va_copy __va_copy
|
||||
|
15
src/http.c
15
src/http.c
@ -670,11 +670,11 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
char t1[MG_PATH_MAX], t2[sizeof(t1)];
|
||||
t1[0] = t2[0] = '\0';
|
||||
|
||||
if (realpath(opts->root_dir, t1) == NULL)
|
||||
if (realpath(opts->root_dir, t1) == NULL) {
|
||||
LOG(LL_ERROR, ("realpath(%s): %d", opts->root_dir, errno));
|
||||
|
||||
if (!mg_is_dir(t1)) {
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", t1);
|
||||
mg_http_reply(c, 400, "", "Bad web root [%s]\n", opts->root_dir);
|
||||
} else if (!mg_is_dir(t1)) {
|
||||
mg_http_reply(c, 400, "", "Invalid web root [%s]\n", t1);
|
||||
} else {
|
||||
// NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for
|
||||
// the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
|
||||
@ -686,8 +686,11 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
n2 = strlen(t1);
|
||||
while (n2 > 0 && t1[n2 - 1] == '/') t1[--n2] = 0;
|
||||
|
||||
if (realpath(t1, t2) == NULL)
|
||||
if (realpath(t1, t2) == NULL) {
|
||||
LOG(LL_ERROR, ("realpath(%s): %d", t1, errno));
|
||||
mg_http_reply(c, 400, "", "Error serving [%s]\n", t1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mg_is_dir(t2)) {
|
||||
strncat(t2, "/index.html", sizeof(t2) - strlen(t2) - 1);
|
||||
@ -697,7 +700,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
|
||||
if (strlen(t2) < n1 || memcmp(t1, t2, n1) != 0) {
|
||||
// Requested file is located outside root directory, fail
|
||||
mg_http_reply(c, 404, "", "Not found %.*s\n", (int) hm->uri.len,
|
||||
mg_http_reply(c, 404, "", "Invalid URI [%.*s]\n", (int) hm->uri.len,
|
||||
hm->uri.ptr);
|
||||
} else {
|
||||
FILE *fp = mg_fopen(t2, "r");
|
||||
|
@ -496,7 +496,7 @@ static void test_http_server(void) {
|
||||
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /badroot HTTP/1.0\r\n\n") == 400);
|
||||
#if MG_ARCH == MG_ARCH_WIN32
|
||||
ASSERT(cmpbody(buf, "Bad web root [Z:\\BAAADDD!]\n") == 0);
|
||||
ASSERT(cmpbody(buf, "Invalid web root [Z:\\BAAADDD!]\n") == 0);
|
||||
#else
|
||||
// LOG(LL_INFO, ("--> [%s]", buf));
|
||||
ASSERT(cmpbody(buf, "Bad web root [/BAAADDD!]\n") == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user