GNOME Bugzilla – Bug 653258
Directory traversal bug in soup-uri.c using url-encoded periods
Last modified: 2011-07-28 17:55:20 UTC
While using gupnp which relies on libsoup, I saw a directory traversal attack was possible by url-encoding double-period segments (%2e) in the URI. In libsoup/soup-uri.c, adding this code prevents the vulnerability for me as a quick-fix: /* Remove url-encoded ".." */ for (p = uri->path + 1; *p; ) { if ( strncmp(p, "..", 2 == 0 )) { memmove (p, p + 2, strlen (p + 2) + 1); p = uri->path + 1; } else if ( strncmp (p, "%2e%2e", 6) == 0 || strncmp (p, "%2e%2E", 6) == 0 || strncmp (p, "%2E%2e", 6) == 0 || strncmp (p, "%2E%2E", 6) == 0 ) { memmove (p, p + 2, strlen (p + 2) + 1); p += 6; } else p++; } /* Remove "./" where "." is a complete segment. */ Example of the vulnerability, connecting to a GUPnP server: > # telnet 198.18.9.240 39137 > Trying 198.18.9.240... > Connected to 198.18.9.240. > Escape character is '^]'. > GET /%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f > %2e%2e%2f%2e%2e%2fetc%2fpasswd HTTP/1.0 > > HTTP/1.0 200 OK > Date: Fri, 15 Oct 2010 14:51:37 GMT > Content-Type: text/plain > Accept-Ranges: bytes > Content-Length: 493 > > root:x:0:0:root:/root:/bin/sh -mike
I can't reproduce this with tests/simple-httpd in the libsoup sources, and I can't figure out how to make gupnp's tests/test-server work. Can you provided more detailed instructions on how to reproduce?
Here is a very basic UPnP server (borrowed from gupnp/examples/light-server.c ), it might be easier to get working: #include <libgupnp/gupnp.h> #include <stdlib.h> #include <gmodule.h> int main (int argc, char **argv) { GMainLoop *main_loop; GError *error = NULL; GUPnPContext *context; GUPnPRootDevice *dev; g_thread_init (NULL); g_type_init (); /* Create the UPnP context */ context = gupnp_context_new (NULL, argv[1], 0, &error); if (error) { g_printerr ("Error creating the GUPnP context: %s\n", error->message); g_error_free (error); return EXIT_FAILURE; } /* Create root device */ dev = gupnp_root_device_new (context, "BinaryLight1.xml", "/tmp); gupnp_root_device_set_available (dev, TRUE); /* Run the main loop */ main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); /* Cleanup */ g_main_loop_unref (main_loop); g_object_unref (dev); g_object_unref (context); return EXIT_SUCCESS; } Copy that into gupnp-0.x.y/examples/server.c and compile, then copy the provided BinaryLight1.xml into your /tmp directory before launching the server with ' ./server eth0 '. If you don't work with UPnP much, which listens for broadcast packets and then unicasts back a response including the high random port to connect to the server on via HTTP, you can find the listening port of the server by doing your OS equivalent of 'netstat -ant'. Then try the telnet and GET above to that port. You could also just use a web browser instead of telnet. -mike
Created attachment 190933 [details] [review] SoupServer: fix to not allow smuggling ".." into path When SoupServer:raw-paths was set (the default), it was possible to sneak ".." segments into the path passed to the SoupServerHandler, which could then end up tricking some handlers into retrieving arbitrary files from the filesystem. Fix that.
Does this patch look right? Does it leave any holes still? Presumably this affects more than just test programs (Rygel?), and we're going to have to put out a security thingamabob about it...
I can confirm that the testcase works against rygel...
This is now CVE-2011-2524, and Red Hat's security team is dealing with jumping through the requisite hoops. (And this bug is currently private to the people already cc:ed on it.)
Is this patch final? I would like to privately inform vendors about this issue and propose a Co-ordinated release date of 28-July-2011. Does anyone copied on this email have any objections?
The patch is final unless anyone finds a way to exploit the bug still with that patch
fixed in master (libsoup-2.35.4) and gnome-3-0 branch (libsoup-2.34.3), and tarballs uploaded