diff options
author | Ignacio Casal Quinteiro <qignacio@amazon.com> | 2019-08-26 12:54:09 +0200 |
---|---|---|
committer | Claudio Saavedra <csaavedra@igalia.com> | 2019-09-11 16:49:02 +0300 |
commit | 515c8aebec04e8df33bcb0e1fd92c82533a52185 (patch) | |
tree | ab48658ca74bf746e5f2fea197b0ea75ca18402f | |
parent | 716acf96c8368ad17c6a257890387659def591e5 (diff) | |
download | libsoup-515c8aebec04e8df33bcb0e1fd92c82533a52185.tar.gz |
SoupServer: fix to not allow smuggling ".." into path
This was already fixed for Unix like systems but it was still
possible to smuggle .. into a windows like server.
-rw-r--r-- | libsoup/soup-server.c | 10 | ||||
-rw-r--r-- | tests/server-test.c | 66 |
2 files changed, 75 insertions, 1 deletions
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c index 58d9574f..160d281f 100644 --- a/libsoup/soup-server.c +++ b/libsoup/soup-server.c @@ -1303,7 +1303,15 @@ got_headers (SoupMessage *msg, SoupClientContext *client) decoded_path = soup_uri_decode (uri->path); if (strstr (decoded_path, "/../") || - g_str_has_suffix (decoded_path, "/..")) { + g_str_has_suffix (decoded_path, "/..") +#ifdef G_OS_WIN32 + || + strstr (decoded_path, "\\..\\") || + strstr (decoded_path, "/..\\") || + strstr (decoded_path, "\\../") || + g_str_has_suffix (decoded_path, "\\..") +#endif + ) { /* Introducing new ".." segments is not allowed */ g_free (decoded_path); soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); diff --git a/tests/server-test.c b/tests/server-test.c index cf132b33..8976103e 100644 --- a/tests/server-test.c +++ b/tests/server-test.c @@ -275,6 +275,72 @@ do_dot_dot_test (ServerData *sd, gconstpointer test_data) soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); + uri = soup_uri_new_with_base (sd->base_uri, "/%2e%2e%2ftest"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + +#ifdef G_OS_WIN32 + uri = soup_uri_new_with_base (sd->base_uri, "\\..%5Ctest"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "\\../test"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "%5C..%2ftest"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "/..\\test"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "%2f..%5Ctest"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "\\%2e%2e%5ctest"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); + + uri = soup_uri_new_with_base (sd->base_uri, "\\..%%35%63..%%35%63test"); + msg = soup_message_new_from_uri ("GET", uri); + soup_uri_free (uri); + + soup_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); + g_object_unref (msg); +#endif + soup_test_session_abort_unref (session); } |