Here are the full advisories: {{{ Subversion HTTP servers up to 1.7.8 (inclusive) are vulnerable to a remotely triggerable excessive memory use, which could result in a Denial of Service. Summary: ======== Subversion's mod_dav_svn Apache HTTPD server module will use excessive amounts of memory when a large number of properties are set or deleted on a node. This can lead to a DoS. There are no known instances of this problem being observed in the wild. 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: ======== Setting or deleting a large number of properties on a node (file or directory) will result in a large amount of memory use. Due to the memory pooling behavior of Apache httpd and Subversion the completion of the request will not result in the immediate release of memory used. Repeated commits with the same properties will result in each httpd process plateauing out at some amount of memory. This could result in a Denial of Service if the system is exhausted of all available memory. Severity: ========= CVSSv2 Base Score: 4.9 CVSSv2 Base Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C We consider this to be a medium risk vulnerability. In order to take advantage of this attack the attacker would require write access to the repository. Most configurations require authentication to commit changes and so anonymous users would not be able to use this attack in these cases. The impact of using this memory varies wildly based on operating system and httpd configuration. Some operating systems may kill off processes or crash if too much memory is used. The Apache httpd configuration option of MaxRequestsPerChild may restart a process after a certain number of requests and limit the impact of accidental exercise of this issue. However, a determined attacker could repeat the commit of a large number of properties or increase the number of properties sufficiently to mitigate any countermeasures. 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 There is no effective configuration that can mitigate the issue entirely however the use of ulimit (or the equivalent) to set memory limits for processes may help prevent the impact affecting other services running on the same machine. References: =========== CVE-2013-1845 (Subversion) Reported by: ============ Alexander Klink, n.runs Patches: ======== Patch against 1.6.20: [[[ Index: subversion/mod_dav_svn/dav_svn.h =================================================================== --- subversion/mod_dav_svn/dav_svn.h (revision 1461956) +++ subversion/mod_dav_svn/dav_svn.h (working copy) @@ -254,6 +254,9 @@ struct dav_resource_private { interface (ie: /path/to/item?p=PEGREV]? */ svn_boolean_t pegged; + /* Cache any revprop change error */ + svn_error_t *revprop_error; + /* Pool to allocate temporary data from */ apr_pool_t *pool; }; Index: subversion/mod_dav_svn/deadprops.c =================================================================== --- subversion/mod_dav_svn/deadprops.c (revision 1461956) +++ subversion/mod_dav_svn/deadprops.c (working copy) @@ -49,8 +49,7 @@ struct dav_db { struct dav_deadprop_rollback { - dav_prop_name name; - svn_string_t value; + int dummy; }; @@ -134,6 +133,7 @@ save_value(dav_db *db, const dav_prop_name *name, { const char *propname; svn_error_t *serr; + apr_pool_t *subpool; /* get the repos-local name */ get_repos_propname(db, name, &propname); @@ -151,10 +151,14 @@ save_value(dav_db *db, const dav_prop_name *name, } /* Working Baseline or Working (Version) Resource */ + + /* A subpool to cope with mod_dav making multiple calls, e.g. during + PROPPATCH with multiple values. */ + subpool = svn_pool_create(db->resource->pool); if (db->resource->baselined) if (db->resource->working) serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn, - propname, value, db->resource->pool); + propname, value, subpool); else { /* ### VIOLATING deltaV: you can't proppatch a baseline, it's @@ -168,19 +172,29 @@ save_value(dav_db *db, const dav_prop_name *name, propname, value, TRUE, TRUE, db->authz_read_func, db->authz_read_baton, - db->resource->pool); + subpool); + /* mod_dav doesn't handle the returned error very well, it + generates its own generic error that will be returned to + the client. Cache the detailed error here so that it can + be returned a second time when the rollback mechanism + triggers. */ + if (serr) + db->resource->info->revprop_error = svn_error_dup(serr); + /* Tell the logging subsystem about the revprop change. */ dav_svn__operational_log(db->resource->info, svn_log__change_rev_prop( db->resource->info->root.rev, propname, - db->resource->pool)); + subpool)); } else serr = svn_repos_fs_change_node_prop(db->resource->info->root.root, get_repos_path(db->resource->info), - propname, value, db->resource->pool); + propname, value, subpool); + svn_pool_destroy(subpool); + if (serr != NULL) return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, NULL, @@ -395,6 +409,7 @@ db_remove(dav_db *db, const dav_prop_name *name) { svn_error_t *serr; const char *propname; + apr_pool_t *subpool; /* get the repos-local name */ get_repos_propname(db, name, &propname); @@ -403,6 +418,10 @@ db_remove(dav_db *db, const dav_prop_name *name) if (propname == NULL) return NULL; + /* A subpool to cope with mod_dav making multiple calls, e.g. during + PROPPATCH with multiple values. */ + subpool = svn_pool_create(db->resource->pool); + /* Working Baseline or Working (Version) Resource */ if (db->resource->baselined) if (db->resource->working) @@ -419,11 +438,12 @@ db_remove(dav_db *db, const dav_prop_name *name) propname, NULL, TRUE, TRUE, db->authz_read_func, db->authz_read_baton, - db->resource->pool); + subpool); else serr = svn_repos_fs_change_node_prop(db->resource->info->root.root, get_repos_path(db->resource->info), - propname, NULL, db->resource->pool); + propname, NULL, subpool); + svn_pool_destroy(subpool); if (serr != NULL) return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "could not remove a property", @@ -598,19 +618,14 @@ db_get_rollback(dav_db *db, const dav_prop_name *name, dav_deadprop_rollback **prollback) { - dav_error *err; - dav_deadprop_rollback *ddp; - svn_string_t *propval; + /* This gets called by mod_dav in preparation for a revprop change. + mod_dav_svn doesn't need to make any changes during rollback, but + we want the rollback mechanism to trigger. Making changes in + response to post-revprop-change hook errors would be positively + wrong. */ - if ((err = get_value(db, name, &propval)) != NULL) - return err; + *prollback = apr_palloc(db->p, sizeof(dav_deadprop_rollback)); - ddp = apr_palloc(db->p, sizeof(*ddp)); - ddp->name = *name; - ddp->value.data = propval ? propval->data : NULL; - ddp->value.len = propval ? propval->len : 0; - - *prollback = ddp; return NULL; } @@ -618,12 +633,20 @@ db_get_rollback(dav_db *db, static dav_error * db_apply_rollback(dav_db *db, dav_deadprop_rollback *rollback) { - if (rollback->value.data == NULL) - { - return db_remove(db, &rollback->name); - } + dav_error *derr; - return save_value(db, &rollback->name, &rollback->value); + if (! db->resource->info->revprop_error) + return NULL; + + /* Returning the original revprop change error here will cause this + detailed error to get returned to the client in preference to the + more generic error created by mod_dav. */ + derr = dav_svn__convert_err(db->resource->info->revprop_error, + HTTP_INTERNAL_SERVER_ERROR, NULL, + db->resource->pool); + db->resource->info->revprop_error = NULL; + + return derr; } ]]] Patch against 1.7.8: [[[ Index: subversion/mod_dav_svn/deadprops.c =================================================================== --- subversion/mod_dav_svn/deadprops.c (revision 1458455) +++ subversion/mod_dav_svn/deadprops.c (working copy) @@ -168,6 +168,7 @@ save_value(dav_db *db, const dav_prop_name *name, const char *propname; svn_error_t *serr; const dav_resource *resource = db->resource; + apr_pool_t *subpool; /* get the repos-local name */ get_repos_propname(db, name, &propname); @@ -202,6 +203,9 @@ save_value(dav_db *db, const dav_prop_name *name, */ + /* A subpool to cope with mod_dav making multiple calls, e.g. during + PROPPATCH with multiple values. */ + subpool = svn_pool_create(db->resource->pool); if (db->resource->baselined) { if (db->resource->working) @@ -208,7 +212,7 @@ save_value(dav_db *db, const dav_prop_name *name, { serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, propname, value, - resource->pool); + subpool); } else { @@ -219,7 +223,7 @@ save_value(dav_db *db, const dav_prop_name *name, TRUE, TRUE, db->authz_read_func, db->authz_read_baton, - resource->pool); + subpool); /* Prepare any hook failure message to get sent over the wire */ if (serr) @@ -242,20 +246,21 @@ save_value(dav_db *db, const dav_prop_name *name, dav_svn__operational_log(resource->info, svn_log__change_rev_prop( resource->info->root.rev, - propname, resource->pool)); + propname, subpool)); } } else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION) { serr = svn_repos_fs_change_txn_prop(resource->info->root.txn, - propname, value, resource->pool); + propname, value, subpool); } else { serr = svn_repos_fs_change_node_prop(resource->info->root.root, get_repos_path(resource->info), - propname, value, resource->pool); + propname, value, subpool); } + svn_pool_destroy(subpool); if (serr != NULL) return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, @@ -540,6 +545,7 @@ db_remove(dav_db *db, const dav_prop_name *name) { svn_error_t *serr; const char *propname; + apr_pool_t *subpool; /* get the repos-local name */ get_repos_propname(db, name, &propname); @@ -548,11 +554,15 @@ db_remove(dav_db *db, const dav_prop_name *name) if (propname == NULL) return NULL; + /* A subpool to cope with mod_dav making multiple calls, e.g. during + PROPPATCH with multiple values. */ + subpool = svn_pool_create(db->resource->pool); + /* Working Baseline or Working (Version) Resource */ if (db->resource->baselined) if (db->resource->working) serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn, - propname, NULL, db->resource->pool); + propname, NULL, subpool); else /* ### VIOLATING deltaV: you can't proppatch a baseline, it's not a working resource! But this is how we currently @@ -564,11 +574,12 @@ db_remove(dav_db *db, const dav_prop_name *name) propname, NULL, NULL, TRUE, TRUE, db->authz_read_func, db->authz_read_baton, - db->resource->pool); + subpool); else serr = svn_repos_fs_change_node_prop(db->resource->info->root.root, get_repos_path(db->resource->info), - propname, NULL, db->resource->pool); + propname, NULL, subpool); + svn_pool_destroy(subpool); if (serr != NULL) return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "could not remove a property", ]]] }}} {{{ 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 LOCK 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. 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 a LOCK request against an activity URL, e.g. curl -u user:pass -X LOCK --data-binary @lock_body 'http://127.0.0.1:8080/repo/!svn/act/foo' Where a file exists named lock_body and has the following contents: http://example.com/ An activity URL is used by the server to map transactions in the repository to an incoming commit by a client. They are created by using the MKACTIVITY http method on the activity URL the client wishes to create. Activity URLs following the pattern of having /!svn/act/$uuid where $uuid is some unique id the client chooses to use. The denial of service described here issues a LOCK 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). The invalid memory access causes the httpd child process to segfault. The auto-versioning feature of Subversion impacts the behavior of LOCK. If SVNAutoversioning is set to 'on' in the httpd configuration and the User-Agent of the client does not contain 'SVN/' then the activity URL does not need to be valid for this crash to occur, i.e., the URL the LOCK is run against need not to have ever had MKACTIVITY run against it. Severity: ========= CVSSv2 Base Score: 2.1 CVSSv2 Base Vector: AV:N/AC:H/Au:S/C:N/I:N/A:P We consider this to be a low risk vulnerability. In order to take advantage of this attack the attacker would need to be authenticated, since the LOCK method requires authentication in order to work. 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 LOCK 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} !=MKACTIVITY RewriteCond %{REQUEST_METHOD} !=DELETE 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-1846 (Subversion) Reported by: ============ Ben Reser, WANdisco Patches: ======== These patches also fix the flaw in CVE-2013-1847. Patch against 1.7.8: [[[ Index: subversion/mod_dav_svn/lock.c =================================================================== --- subversion/mod_dav_svn/lock.c (revision 1458455) +++ subversion/mod_dav_svn/lock.c (working copy) @@ -640,7 +640,20 @@ append_locks(dav_lockdb *lockdb, svn_lock_t *slock; svn_error_t *serr; dav_error *derr; + dav_svn_repos *repos = resource->info->repos; + + /* We don't allow anonymous locks */ + if (! repos->username) + return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + DAV_ERR_LOCK_SAVE_LOCK, + "Anonymous lock creation is not allowed."); + /* Not a path in the repository so can't lock it. */ + if (! resource->info->repos_path) + return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, + DAV_ERR_LOCK_SAVE_LOCK, + "Attempted to lock path not in repository."); + /* If the resource's fs path is unreadable, we don't allow a lock to be created on it. */ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM, @@ -663,7 +676,6 @@ append_locks(dav_lockdb *lockdb, svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_msg; - dav_svn_repos *repos = resource->info->repos; apr_hash_t *revprop_table = apr_hash_make(resource->pool); apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING, svn_string_create(repos->username, @@ -741,7 +753,7 @@ append_locks(dav_lockdb *lockdb, /* Convert the dav_lock into an svn_lock_t. */ derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, - info, resource->info->repos->is_svn_client, + info, repos->is_svn_client, resource->pool); if (derr) return derr; @@ -748,7 +760,7 @@ append_locks(dav_lockdb *lockdb, /* Now use the svn_lock_t to actually perform the lock. */ serr = svn_repos_fs_lock(&slock, - resource->info->repos->repos, + repos->repos, slock->path, slock->token, slock->comment, ]]] Patch against 1.6.20: [[[ Index: subversion/mod_dav_svn/lock.c =================================================================== --- subversion/mod_dav_svn/lock.c (revision 1459696) +++ subversion/mod_dav_svn/lock.c (working copy) @@ -634,7 +634,20 @@ append_locks(dav_lockdb *lockdb, svn_lock_t *slock; svn_error_t *serr; dav_error *derr; + dav_svn_repos *repos = resource->info->repos; + + /* We don't allow anonymous locks */ + if (! repos->username) + return dav_new_error(resource->pool, HTTP_UNAUTHORIZED, + DAV_ERR_LOCK_SAVE_LOCK, + "Anonymous lock creation is not allowed."); + /* Not a path in the repository so can't lock it. */ + if (! resource->info->repos_path) + return dav_new_error(resource->pool, HTTP_BAD_REQUEST, + DAV_ERR_LOCK_SAVE_LOCK, + "Attempted to lock path not in repository."); + /* If the resource's fs path is unreadable, we don't allow a lock to be created on it. */ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM, @@ -657,7 +670,6 @@ append_locks(dav_lockdb *lockdb, svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_msg; - dav_svn_repos *repos = resource->info->repos; apr_hash_t *revprop_table = apr_hash_make(resource->pool); apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING, svn_string_create(repos->username, @@ -734,7 +746,7 @@ append_locks(dav_lockdb *lockdb, /* Convert the dav_lock into an svn_lock_t. */ derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, - info, resource->info->repos->is_svn_client, + info, repos->is_svn_client, resource->pool); if (derr) return derr; @@ -741,7 +753,7 @@ append_locks(dav_lockdb *lockdb, /* Now use the svn_lock_t to actually perform the lock. */ serr = svn_repos_fs_lock(&slock, - resource->info->repos->repos, + repos->repos, slock->path, slock->token, slock->comment, ]]] }}} {{{ Subversion HTTP servers 1.6.0 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 in some circumstances when a LOCK request is made against a non-existent URL. This can lead to a DoS. There are no known instances of this problem being observed in the wild. Known vulnerable: ================= Subversion HTTPD servers 1.6.0 through 1.6.20 (inclusive) 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 a LOCK request against a URL for a path that does not exist in the repository or an invalid activity URL where authentication is not required for the LOCK method. For example if the repository does not contain a file named foo: curl -X LOCK --data-binary @lock_body 'http://127.0.0.1:8080/repo/foo' Where a file exists named lock_body and has the following contents: http://example.com/ Such a request would normally be rejected since anonymous locks are not supported and in most cases locks against non-existant paths are not supported. However, when auto-versioning is enabled and the client is a non-SVN DAV client, we support locking non-existant files. The code to handle this neglected to check that the username was set before trying to copy it into the revision properties hash. This results in a segfault (NULL dereference) and thus a crash of the httpd child process. Severity: ========= CVSSv2 Base Score: 2.6 CVSSv2 Base Vector: AV:N/AC:H/Au:N/C:N/I:N/A:P We consider this to be a low risk vulnerability. In most configurations authentication will be required for the LOCK method which would prevent this attack entirely. However, sites that are not using locks and that allow anonymous write access may have this configuration. 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 LOCK 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 should ensure that LOCK requests require authentication against their repositories. Typical configurations either have a 'Require' statement forcing all requests against the repository to be authenticated or use a 'LimitExcept' block to only allow read-only methods without authentication. See this section of the Subversion book for more details: http://svnbook.red-bean.com/en/1.7/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authz.blanket References: =========== CVE-2013-1847 (Subversion) Reported by: ============ Philip Martin & Ben Reser, WANdisco Patches: ======== These patches also fix the flaw in CVE-2013-1846. Patch against 1.7.8: [[[ Index: subversion/mod_dav_svn/lock.c =================================================================== --- subversion/mod_dav_svn/lock.c (revision 1458455) +++ subversion/mod_dav_svn/lock.c (working copy) @@ -640,7 +640,20 @@ append_locks(dav_lockdb *lockdb, svn_lock_t *slock; svn_error_t *serr; dav_error *derr; + dav_svn_repos *repos = resource->info->repos; + + /* We don't allow anonymous locks */ + if (! repos->username) + return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + DAV_ERR_LOCK_SAVE_LOCK, + "Anonymous lock creation is not allowed."); + /* Not a path in the repository so can't lock it. */ + if (! resource->info->repos_path) + return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, + DAV_ERR_LOCK_SAVE_LOCK, + "Attempted to lock path not in repository."); + /* If the resource's fs path is unreadable, we don't allow a lock to be created on it. */ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM, @@ -663,7 +676,6 @@ append_locks(dav_lockdb *lockdb, svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_msg; - dav_svn_repos *repos = resource->info->repos; apr_hash_t *revprop_table = apr_hash_make(resource->pool); apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING, svn_string_create(repos->username, @@ -741,7 +753,7 @@ append_locks(dav_lockdb *lockdb, /* Convert the dav_lock into an svn_lock_t. */ derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, - info, resource->info->repos->is_svn_client, + info, repos->is_svn_client, resource->pool); if (derr) return derr; @@ -748,7 +760,7 @@ append_locks(dav_lockdb *lockdb, /* Now use the svn_lock_t to actually perform the lock. */ serr = svn_repos_fs_lock(&slock, - resource->info->repos->repos, + repos->repos, slock->path, slock->token, slock->comment, ]]] Patch against 1.6.20: [[[ Index: subversion/mod_dav_svn/lock.c =================================================================== --- subversion/mod_dav_svn/lock.c (revision 1459696) +++ subversion/mod_dav_svn/lock.c (working copy) @@ -634,7 +634,20 @@ append_locks(dav_lockdb *lockdb, svn_lock_t *slock; svn_error_t *serr; dav_error *derr; + dav_svn_repos *repos = resource->info->repos; + + /* We don't allow anonymous locks */ + if (! repos->username) + return dav_new_error(resource->pool, HTTP_UNAUTHORIZED, + DAV_ERR_LOCK_SAVE_LOCK, + "Anonymous lock creation is not allowed."); + /* Not a path in the repository so can't lock it. */ + if (! resource->info->repos_path) + return dav_new_error(resource->pool, HTTP_BAD_REQUEST, + DAV_ERR_LOCK_SAVE_LOCK, + "Attempted to lock path not in repository."); + /* If the resource's fs path is unreadable, we don't allow a lock to be created on it. */ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM, @@ -657,7 +670,6 @@ append_locks(dav_lockdb *lockdb, svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_msg; - dav_svn_repos *repos = resource->info->repos; apr_hash_t *revprop_table = apr_hash_make(resource->pool); apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING, svn_string_create(repos->username, @@ -734,7 +746,7 @@ append_locks(dav_lockdb *lockdb, /* Convert the dav_lock into an svn_lock_t. */ derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, - info, resource->info->repos->is_svn_client, + info, repos->is_svn_client, resource->pool); if (derr) return derr; @@ -741,7 +753,7 @@ append_locks(dav_lockdb *lockdb, /* Now use the svn_lock_t to actually perform the lock. */ serr = svn_repos_fs_lock(&slock, - resource->info->repos->repos, + repos->repos, slock->path, slock->token, slock->comment, ]]] }}} {{{ 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 ]]] }}} {{{ Subversion HTTP servers 1.7.0 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 log REPORT request receives a limit that is out of the allowed range. This can lead to a DoS. There are no known instances of this problem being used as a DoS in the wild. Known vulnerable: ================= Subversion HTTPD servers 1.7.0 through 1.7.8 (inclusive) Known fixed: ============ Subversion 1.7.9 svnserve (any version) is not vulnerable Details: ======== The vulnerability can be triggered by doing a log REPORT request with a limit outside the allowed range. For example where http://127.0.0.1:8080/repo is the root of a repository: curl -X REPORT --data-binary @log_report 'http://127.0.0.1:8080/repo/!svn/bc/1/' Where a file exists named log_report and has the following contents: 0 1 9223372036854775807 The limit is defined as an int, which is generally a 32-bit value. Prior to 1.7.0 such a request would have caused the limit to wrap and not necessarily reflected what the requestor intended. In 1.7.0 code was added to detect this and reject out of range values as errors. However, the error code ends up causing the attempted use of a variable that has not been set, resulting in the segfault. Severity: ========= CVSSv2 Base Score: 5.0 CVSSv2 Base Vector: AV:N/AC:L/Au:N/C:N/I:N/A:P We consider this to be a medium risk vulnerability. Configurations which allow anonymous read access to the repository will be vulnerable to this without authentication. 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 REPORT request from the attacker. Recommendations: ================ We recommend all users to upgrade to Subversion 1.7.9. Users of Subversion 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 There is no httpd configuration that can counter this issue. References: =========== CVE-2013-1884 (Subversion) Reported by: ============ Greg McMullin, Stefan Fuhrmann, Philip Martin & Ben Reser, WANdisco Patches: ======== Patch against 1.7.8: [[[ Index: subversion/mod_dav_svn/reports/log.c =================================================================== --- subversion/mod_dav_svn/reports/log.c (revision 1459527) +++ subversion/mod_dav_svn/reports/log.c (working copy) @@ -341,10 +341,9 @@ dav_svn__log_report(const dav_resource *resource, dav_xml_get_cdata(child, resource->pool, 1)); if (serr) { - derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, + return dav_svn__convert_err(serr, HTTP_BAD_REQUEST, "Malformed CDATA in element " "\"limit\"", resource->pool); - goto cleanup; } } else if (strcmp(child->name, "discover-changed-paths") == 0) ]]] }}}