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)
]]]
}}}