diff --git a/src/wiki.c b/src/wiki.c index 2413d05..2062bce 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_name[0])) + return FALSE; + + if (strstr(page_name, "..")) + 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");