aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-04-16 10:00:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-04-16 10:07:33 +0200
commitbae8f7eaf2997938615ed4282d6d93d3aa1f3fc1 (patch)
tree034d95d6c9a6a2c9dc6978774322aea0572d6a33
parent02d650e15919e48fe031308c77c041159c0e3631 (diff)
downloadbusybox-w32-bae8f7eaf2997938615ed4282d6d93d3aa1f3fc1.tar.gz
busybox-w32-bae8f7eaf2997938615ed4282d6d93d3aa1f3fc1.tar.bz2
busybox-w32-bae8f7eaf2997938615ed4282d6d93d3aa1f3fc1.zip
httpd: do not percent-decode URI if proxying
The proxying is documented as follows: P:/url:[http://]hostname[:port]/new/path Howeverm urlcopy is not a true copy anymore when it is fdprint'ed to proxy_fd, this is because percent_decode_in_place() is called after the copy is created. This breaks reverse proxying all URIs containing percent encoded spaces, e.g. - because a decoded URI will be printed out to proxy_fd instead of the original. The fix keeps the logic in place to canonicalize the uri first, before reverse proxying (one could argue that the uri should be proxied completely unaltered, except for the prefix rewrite). function old new delta handle_incoming_and_exit 2752 2792 +40 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index c486197b8..bc0e386ea 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1817,7 +1817,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1817 log_and_exit(); 1817 log_and_exit();
1818} 1818}
1819 1819
1820static void send_HTTP_FORBIDDEN_and_exit_if_denied_ip(void) 1820static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(void)
1821{ 1821{
1822 Htaccess_IP *cur; 1822 Htaccess_IP *cur;
1823 1823
@@ -2195,6 +2195,24 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2195 send_headers_and_exit(HTTP_NOT_FOUND); 2195 send_headers_and_exit(HTTP_NOT_FOUND);
2196 } 2196 }
2197 2197
2198#if ENABLE_FEATURE_HTTPD_PROXY
2199 proxy_entry = find_proxy_entry(urlcopy);
2200 if (proxy_entry)
2201 header_buf = header_ptr = xmalloc(IOBUF_SIZE);
2202 else
2203#endif
2204 {
2205 /* (If not proxying,) decode URL escape sequences */
2206 tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1);
2207 if (tptr == NULL)
2208 send_headers_and_exit(HTTP_BAD_REQUEST);
2209 if (tptr == urlcopy + 1) {
2210 /* '/' or NUL is encoded */
2211 send_headers_and_exit(HTTP_NOT_FOUND);
2212 }
2213//should path canonicalization also be conditional on not proxying?
2214 }
2215
2198 /* Canonicalize path */ 2216 /* Canonicalize path */
2199 /* Algorithm stolen from libbb bb_simplify_path(), 2217 /* Algorithm stolen from libbb bb_simplify_path(),
2200 * but don't strdup, retain trailing slash, protect root */ 2218 * but don't strdup, retain trailing slash, protect root */
@@ -2224,7 +2242,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2224 } 2242 }
2225 } 2243 }
2226 *++urlp = *tptr; 2244 *++urlp = *tptr;
2227 if (*urlp == '\0') 2245 if (*tptr == '\0')
2228 break; 2246 break;
2229 next_char: 2247 next_char:
2230 tptr++; 2248 tptr++;
@@ -2242,24 +2260,18 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2242 bb_error_msg("url:%s", urlcopy); 2260 bb_error_msg("url:%s", urlcopy);
2243 2261
2244 tptr = urlcopy; 2262 tptr = urlcopy;
2245 send_HTTP_FORBIDDEN_and_exit_if_denied_ip(); 2263 if_ip_denied_send_HTTP_FORBIDDEN_and_exit();
2246 while ((tptr = strchr(tptr + 1, '/')) != NULL) { 2264 while ((tptr = strchr(tptr + 1, '/')) != NULL) {
2247 /* have path1/path2 */ 2265 /* have path1/path2 */
2248 *tptr = '\0'; 2266 *tptr = '\0';
2249 if (is_directory(urlcopy + 1, /*followlinks:*/ 1)) { 2267 if (is_directory(urlcopy + 1, /*followlinks:*/ 1)) {
2250 /* may have subdir config */ 2268 /* may have subdir config */
2251 parse_conf(urlcopy + 1, SUBDIR_PARSE); 2269 parse_conf(urlcopy + 1, SUBDIR_PARSE);
2252 send_HTTP_FORBIDDEN_and_exit_if_denied_ip(); 2270 if_ip_denied_send_HTTP_FORBIDDEN_and_exit();
2253 } 2271 }
2254 *tptr = '/'; 2272 *tptr = '/';
2255 } 2273 }
2256 2274
2257#if ENABLE_FEATURE_HTTPD_PROXY
2258 proxy_entry = find_proxy_entry(urlcopy);
2259 if (proxy_entry)
2260 header_buf = header_ptr = xmalloc(IOBUF_SIZE);
2261#endif
2262
2263 if (http_major_version >= '0') { 2275 if (http_major_version >= '0') {
2264 /* Request was with "... HTTP/nXXX", and n >= 0 */ 2276 /* Request was with "... HTTP/nXXX", and n >= 0 */
2265 2277