From 5e5c796617e1712905dc5462b94bd5e6c08d15ea Mon Sep 17 00:00:00 2001 From: Alexander Izmailov Date: Wed, 9 Oct 2013 11:48:45 +0400 Subject: [PATCH 1/2] page_name_is_good function --- src/wiki.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/wiki.c b/src/wiki.c index 2413d05..850c9b8 100644 --- a/src/wiki.c +++ b/src/wiki.c @@ -851,6 +851,26 @@ wiki_show_footer(HttpResponse *res) ); } +int page_name_is_good(char* page_name) +{ +/* We should give access only to subdirs of didiwiki root. + I guess that check for absense of '/' is enough. + + TODO: Use realpath() +*/ + if (!page_name) + return FALSE; + + if (!isalnum(page[0])) + return FALSE; + + if (strstr(page, "..")) + return FALSE; + + return TRUE; +} + + void wiki_handle_rest_call(HttpRequest *req, HttpResponse *res, @@ -866,7 +886,7 @@ wiki_handle_rest_call(HttpRequest *req, if (page == NULL) page = http_request_get_query_string(req); - if (page && (access(page, R_OK) == 0)) + if (page && page_name_is_good(page) && (access(page, R_OK) == 0)) { http_response_printf(res, "%s", file_read(page)); http_response_send(res); @@ -879,11 +899,14 @@ wiki_handle_rest_call(HttpRequest *req, if( ( (wikitext = http_request_param_get(req, "text")) != NULL) && ( (page = http_request_param_get(req, "page")) != NULL)) { - file_write(page, wikitext); + if (page_name_is_good(page)) + { + file_write(page, wikitext); http_response_printf(res, "success"); http_response_send(res); return; } + } } else if (!strcmp(func, "page/delete")) { @@ -892,7 +915,7 @@ wiki_handle_rest_call(HttpRequest *req, if (page == NULL) page = http_request_get_query_string(req); - if (page && (unlink(page) > 0)) + if (page && page_name_is_good(page) && (unlink(page) > 0)) { http_response_printf(res, "success"); http_response_send(res); @@ -906,7 +929,7 @@ wiki_handle_rest_call(HttpRequest *req, if (page == NULL) page = http_request_get_query_string(req); - if (page && (access(page, R_OK) == 0)) + if (page && page_name_is_good(page) && (access(page, R_OK) == 0)) { http_response_printf(res, "success"); http_response_send(res); @@ -1005,7 +1028,7 @@ wiki_handle_http_request(HttpRequest *req) /* A little safety. issue a malformed request for any paths, * There shouldn't need to be any.. */ - if (strchr(page, '/')) + if (!page_name_is_good(page)) { http_response_set_status(res, 404, "Not Found"); http_response_printf(res, "404 Not Found\n"); From 57b0399f4dec1bea1542ab3afa89427f08463a9c Mon Sep 17 00:00:00 2001 From: Alexander Izmailov Date: Wed, 3 Sep 2014 21:41:26 +0400 Subject: [PATCH 2/2] fix build --- src/wiki.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wiki.c b/src/wiki.c index 850c9b8..2062bce 100644 --- a/src/wiki.c +++ b/src/wiki.c @@ -861,10 +861,10 @@ int page_name_is_good(char* page_name) if (!page_name) return FALSE; - if (!isalnum(page[0])) + if (!isalnum(page_name[0])) return FALSE; - if (strstr(page, "..")) + if (strstr(page_name, "..")) return FALSE; return TRUE;