Subversion HTTP servers up to 1.7.8 (inclusive) are vulnerable to a remotely triggerable segfault DoS vulnerability. Summary: ======== Subversion's mod_dav_svn Apache HTTPD server module will crash when a PROPFIND request is made against activity URLs. This can lead to a DoS. There are no known instances of this problem being observed in the wild, but the details of how to exploit it have been disclosed on the full disclosure mailing list. Known vulnerable: ================= Subversion HTTPD servers <= 1.6.20 Subversion HTTPD servers 1.7.0 through 1.7.8 (inclusive) Known fixed: ============ Subversion 1.6.21 Subversion 1.7.9 svnserve (any version) is not vulnerable Details: ======== The vulnerability can be triggered by doing the following HTTP requests: MKACTIVITY /egg/!svn/act/foo HTTP/1.1 PROPFIND /egg/!svn/act/foo HTTP/1.1 ('/egg' is the path the repository root) Some background: When an SVN client wants to commit a change to a Subversion repository it must create a transaction to send the changes to before it finally requests that those changes be merged to form a revision. Prior to our HTTPv2 protocol changes (added in Subversion 1.7) this meant creating an activity URL with MKACTIVITY. MKACTIVITY is still supported even in newer servers that support HTTPv2 in order to support older clients. The client generated a UUID and used it as the last component of the URI which it ran MKACTIVITY on (seen as foo above). The repository then tracked these activity URLs (for FSFS via files in $REPO/dav/activities.d), mapping activity URLs to transaction ids used in the repository. The client can issue a DELETE request to explicitly remove an activity URL and some other methods implicitly remove the activity URL. However, the server does not contain any code to cleanup abandoned (i.e. not removed during normal actions) activity URLs, so they may build up over time on a server. The denial of service described here issues a PROPFIND request on an activity URL. There is no meaning to this request in the DAV based HTTP protocols that Subversion uses. There is a flaw in mod_dav_svn that improperly tries to process this request instead of rejecting it and results in an attempt to access invalid memory (NULL). Which results in the httpd process segfaulting and dying. How bad the impact of that is varies based upon the configuration of the httpd server. httpd servers using a prefork MPM will simply start a new process to replace the process that died. Servers using threaded MPMs may be processing other requests in the same process as the process that the attack causes to die. In either case there is an increased processing impact of restarting a process and the cost of per process caches being lost. Severity: ========= CVSSv2 Base Score: 4.3 CVSSv2 Base Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P We consider this to be a medium risk vulnerability. While creating an activity URL is commonly restricted to authorized users, this attack can be exercised if anonymous read access is allowed and existing activity URLs can be guessed. Generally MKACTIVITY is protected by an authentication requirement as it is needed for commit access to the repository. However, this attack does not necessarily require the attacker to execute MKACTIVITY. All the attack needs is a valid activity URL. PROPFIND which is required for the attack would be left open if anonymous read-only access is being allowed. Activity URLs as mentioned above have UUIDs in them. Subversion depends upon the APR-util library to generate the UUID and in many cases APR-util depends upon an OS provided function (uuid_generate or uuid_create on unix OSes and UuidCreate() on Windows). If an OS- provided function is not available, APR-util uses its own internal implementation of UUID generation code. While the various implementations of UUID generation are generally unique, some of them have predictable components such as the time or MAC address of a NIC installed in the machine generating them. Activity URLs as mentioned above might not be cleaned up, so a server may build up old unused activity URLs that remain valid for long periods of time. Combined with the predictability of some UUIDs, there is a small chance for an attacker to guess a valid activity URL and as such not need to issue a MKACTIVITY against the server. Thus allowing this vulnerability to be used against servers without requiring write access. A remote attacker may be able to crash a Subversion server. Many Apache servers will respawn the listener processes, but a determined attacker will be able to crash these processes as they appear, denying service to legitimate users. Servers using threaded MPMs will close the connection on other clients being served by the same process that services the PROPFIND request from the attacker. Recommendations: ================ We recommend all users to upgrade to Subversion 1.7.9. Users of Subversion 1.6.x or 1.7.x who are unable to upgrade may apply the included patch. New Subversion packages can be found at: http://subversion.apache.org/packages.html Administrators that wish to protect against this without patching immediately can apply the following configuration to their httpd.conf file (this uses mod_rewrite so you'll need that module available): [[[ RewriteEngine on RewriteCond %{REQUEST_METHOD} !=DELETE RewriteCond %{REQUEST_METHOD} !=MKACTIVITY RewriteCond %{REQUEST_URI} /!svn/act/[^/]*/*$ RewriteRule .* - [L,F] ]]] The above configuration will not block any useful requests and can be used without concern that it will break anything. References: =========== CVE-2013-1849 (Subversion) Full Disclosure Posting: http://seclists.org/fulldisclosure/2013/Mar/56 Reported by: ============ tytusromekiatomek{_AT_}hushmail.com via the full disclosure mailing list Patches: ======== Patch against 1.6.20 and 1.7.8: [[[ Index: subversion/mod_dav_svn/liveprops.c =================================================================== --- subversion/mod_dav_svn/liveprops.c (revision 1458455) +++ subversion/mod_dav_svn/liveprops.c (working copy) @@ -429,7 +429,8 @@ insert_prop_internal(const dav_resource *resource, svn_filesize_t len = 0; /* our property, but not defined on collection resources */ - if (resource->collection || resource->baselined) + if (resource->type == DAV_RESOURCE_TYPE_ACTIVITY + || resource->collection || resource->baselined) return DAV_PROP_INSERT_NOTSUPP; serr = svn_fs_file_length(&len, resource->info->root.root, @@ -453,7 +454,9 @@ insert_prop_internal(const dav_resource *resource, svn_string_t *pval; const char *mime_type = NULL; - if (resource->baselined && resource->type == DAV_RESOURCE_TYPE_VERSION) + if (resource->type == DAV_RESOURCE_TYPE_ACTIVITY + || (resource->baselined + && resource->type == DAV_RESOURCE_TYPE_VERSION)) return DAV_PROP_INSERT_NOTSUPP; if (resource->type == DAV_RESOURCE_TYPE_PRIVATE ]]]