summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Casal Quinteiro <qignacio@amazon.com>2019-08-26 12:54:09 +0200
committerClaudio Saavedra <csaavedra@igalia.com>2019-09-11 16:49:02 +0300
commit515c8aebec04e8df33bcb0e1fd92c82533a52185 (patch)
treeab48658ca74bf746e5f2fea197b0ea75ca18402f
parent716acf96c8368ad17c6a257890387659def591e5 (diff)
downloadlibsoup-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.c10
-rw-r--r--tests/server-test.c66
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);
}