@@ -851,6 +851,26 @@ wiki_show_footer(HttpResponse *res)
851851 );
852852}
853853
854+ int page_name_is_good (char * page_name )
855+ {
856+ /* We should give access only to subdirs of didiwiki root.
857+ I guess that check for absense of '/' is enough.
858+
859+ TODO: Use realpath()
860+ */
861+ if (!page_name )
862+ return FALSE;
863+
864+ if (!isalnum (page [0 ]))
865+ return FALSE;
866+
867+ if (strstr (page , ".." ))
868+ return FALSE;
869+
870+ return TRUE;
871+ }
872+
873+
854874void
855875wiki_handle_rest_call (HttpRequest * req ,
856876 HttpResponse * res ,
@@ -866,7 +886,7 @@ wiki_handle_rest_call(HttpRequest *req,
866886 if (page == NULL )
867887 page = http_request_get_query_string (req );
868888
869- if (page && ( access (page , R_OK ) == 0 ))
889+ if (page && page_name_is_good ( page ) && ( access (page , R_OK ) == 0 ))
870890 {
871891 http_response_printf (res , "%s" , file_read (page ));
872892 http_response_send (res );
@@ -879,11 +899,14 @@ wiki_handle_rest_call(HttpRequest *req,
879899 if ( ( (wikitext = http_request_param_get (req , "text" )) != NULL )
880900 && ( (page = http_request_param_get (req , "page" )) != NULL ))
881901 {
882- file_write (page , wikitext );
902+ if (page_name_is_good (page ))
903+ {
904+ file_write (page , wikitext );
883905 http_response_printf (res , "success" );
884906 http_response_send (res );
885907 return ;
886908 }
909+ }
887910 }
888911 else if (!strcmp (func , "page/delete" ))
889912 {
@@ -892,7 +915,7 @@ wiki_handle_rest_call(HttpRequest *req,
892915 if (page == NULL )
893916 page = http_request_get_query_string (req );
894917
895- if (page && (unlink (page ) > 0 ))
918+ if (page && page_name_is_good ( page ) && (unlink (page ) > 0 ))
896919 {
897920 http_response_printf (res , "success" );
898921 http_response_send (res );
@@ -906,7 +929,7 @@ wiki_handle_rest_call(HttpRequest *req,
906929 if (page == NULL )
907930 page = http_request_get_query_string (req );
908931
909- if (page && ( access (page , R_OK ) == 0 ))
932+ if (page && page_name_is_good ( page ) && ( access (page , R_OK ) == 0 ))
910933 {
911934 http_response_printf (res , "success" );
912935 http_response_send (res );
@@ -1005,7 +1028,7 @@ wiki_handle_http_request(HttpRequest *req)
10051028 /* A little safety. issue a malformed request for any paths,
10061029 * There shouldn't need to be any..
10071030 */
1008- if (strchr (page , '/' ))
1031+ if (! page_name_is_good (page ))
10091032 {
10101033 http_response_set_status (res , 404 , "Not Found" );
10111034 http_response_printf (res , "<html><body>404 Not Found</body></html>\n" );
0 commit comments