{"action":"created","issue":{"url":"https://api.github.com/repos/civetweb/civetweb/issues/299","repository_url":"https://api.github.com/repos/civetweb/civetweb","labels_url":"https://api.github.com/repos/civetweb/civetweb/issues/299/labels{/name}","comments_url":"https://api.github.com/repos/civetweb/civetweb/issues/299/comments","events_url":"https://api.github.com/repos/civetweb/civetweb/issues/299/events","html_url":"https://github.com/civetweb/civetweb/issues/299","id":149748669,"number":299,"title":"Verifying interpreted path is LFN","user":{"login":"xtne6f","id":2673799,"avatar_url":"https://avatars.githubusercontent.com/u/2673799?v=3","gravatar_id":"","url":"https://api.github.com/users/xtne6f","html_url":"https://github.com/xtne6f","followers_url":"https://api.github.com/users/xtne6f/followers","following_url":"https://api.github.com/users/xtne6f/following{/other_user}","gists_url":"https://api.github.com/users/xtne6f/gists{/gist_id}","starred_url":"https://api.github.com/users/xtne6f/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xtne6f/subscriptions","organizations_url":"https://api.github.com/users/xtne6f/orgs","repos_url":"https://api.github.com/users/xtne6f/repos","events_url":"https://api.github.com/users/xtne6f/events{/privacy}","received_events_url":"https://api.github.com/users/xtne6f/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-04-20T12:03:38Z","updated_at":"2016-04-20T18:49:17Z","closed_at":null,"body":"On Windows, files can be also accessed by SFN (short filename), so, for example, `hide_files_patterns` is almost useless.\r\nThis is my candidate fix for the issue. (sorry this is release-v1.7 based patch.)\r\n\r\n    --- a/civetweb.c\r\n    +++ b/civetweb.c\r\n    @@ -2379,6 +2379,24 @@ static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)\r\n     \r\n    +static int is_existing_long_path(const char *path)\r\n    +{\r\n    +\twchar_t wpath[PATH_MAX];\r\n    +\tchar buf[PATH_MAX], buf2[PATH_MAX];\r\n    +\tDWORD len;\r\n    +\r\n    +\tto_unicode(path, wpath, ARRAY_SIZE(wpath));\r\n    +\tif (WideCharToMultiByte(CP_UTF8, 0, wpath, -1, buf, sizeof(buf), NULL, NULL) != 0) {\r\n    +\t\tlen = GetLongPathNameW(wpath, wpath, ARRAY_SIZE(wpath));\r\n    +\t\tif (len != 0 && len < ARRAY_SIZE(wpath) &&\r\n    +\t\t    WideCharToMultiByte(CP_UTF8, 0, wpath, -1, buf2, sizeof(buf2), NULL, NULL) != 0 &&\r\n    +\t\t    mg_strcasecmp(buf, buf2) == 0) {\r\n    +\t\t\treturn 1;\r\n    +\t\t}\r\n    +\t}\r\n    +\treturn 0;\r\n    +}\r\n    +\r\n     #if defined(_WIN32_WCE)\r\n    @@ -3886,7 +3904,11 @@ interpret_uri(struct mg_connection *conn,   /* in: request */\r\n     \r\n     \t\t/* Local file path and name, corresponding to requested URI\r\n     \t\t * is now stored in \"filename\" variable. */\r\n    -\t\tif (mg_stat(conn, filename, filep)) {\r\n    +\t\tif (mg_stat(conn, filename, filep)\r\n    +#if defined(_WIN32)\r\n    +\t\t    && (filep->membuf || is_existing_long_path(filename))\r\n    +#endif\r\n    +\t\t    ) {\r\n     \t\t\t/* File exists. Check if it is a script type. */\r\n     \t\t\tif (0\r\n     #if !defined(NO_CGI)\r\n    @@ -3928,7 +3950,11 @@ interpret_uri(struct mg_connection *conn,   /* in: request */\r\n     \t\t    NULL) {\r\n     \t\t\tif (strstr(accept_encoding, \"gzip\") != NULL) {\r\n     \t\t\t\tsnprintf(gz_path, sizeof(gz_path), \"%s.gz\", filename);\r\n    -\t\t\t\tif (mg_stat(conn, gz_path, filep)) {\r\n    +\t\t\t\tif (mg_stat(conn, gz_path, filep)\r\n    +#if defined(_WIN32)\r\n    +\t\t\t\t    && (filep->membuf || is_existing_long_path(gz_path))\r\n    +#endif\r\n    +\t\t\t\t    ) {\r\n     \t\t\t\t\tif (filep) {\r\n     \t\t\t\t\t\tfilep->gzipped = 1;\r\n     \t\t\t\t\t\t*is_found = 1;\r\n    @@ -3958,7 +3984,11 @@ interpret_uri(struct mg_connection *conn,   /* in: request */\r\n     \t\t\t\t         filename) > 0\r\n     #endif\r\n     \t\t\t\t     ) &&\r\n    -\t\t\t\t    mg_stat(conn, filename, filep)) {\r\n    +\t\t\t\t    mg_stat(conn, filename, filep)\r\n    +#if defined(_WIN32)\r\n    +\t\t\t\t    && (filep->membuf || is_existing_long_path(filename))\r\n    +#endif\r\n    +\t\t\t\t    ) {\r\n     \t\t\t\t\t/* Shift PATH_INFO block one character right, e.g.\r\n     \t\t\t\t\t * \"/x.cgi/foo/bar\\x00\" => \"/x.cgi\\x00/foo/bar\\x00\"\r\n     \t\t\t\t\t * conn->path_info is pointing to the local variable \"path\"\r\n"},"comment":{"url":"https://api.github.com/repos/civetweb/civetweb/issues/comments/212555961","html_url":"https://github.com/civetweb/civetweb/issues/299#issuecomment-212555961","issue_url":"https://api.github.com/repos/civetweb/civetweb/issues/299","id":212555961,"user":{"login":"xtne6f","id":2673799,"avatar_url":"https://avatars.githubusercontent.com/u/2673799?v=3","gravatar_id":"","url":"https://api.github.com/users/xtne6f","html_url":"https://github.com/xtne6f","followers_url":"https://api.github.com/users/xtne6f/followers","following_url":"https://api.github.com/users/xtne6f/following{/other_user}","gists_url":"https://api.github.com/users/xtne6f/gists{/gist_id}","starred_url":"https://api.github.com/users/xtne6f/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xtne6f/subscriptions","organizations_url":"https://api.github.com/users/xtne6f/orgs","repos_url":"https://api.github.com/users/xtne6f/repos","events_url":"https://api.github.com/users/xtne6f/events{/privacy}","received_events_url":"https://api.github.com/users/xtne6f/received_events","type":"User","site_admin":false},"created_at":"2016-04-20T18:49:17Z","updated_at":"2016-04-20T18:49:17Z","body":"Thank you for your reply.\r\nUmm.., so you should notify `hide_file_patters` is deplicated on Windows in your document.\r\nThen, this issue is not only `hide_file_patters`.\r\nCurrently `.htpasswd` can be readable by every users as `HTPASS~1` on Windows.\r\nFor example, if `lua_script_pattern` is \"**.jpeg\", anyone can read inner image-generator script of `foo.jpeg` as `FOO.JPE`."}}