You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Jan Lehnardt <ja...@apache.org> on 2017/11/14 17:02:52 UTC

Apache CouchDB CVE-2017-12635 and CVE-2017-12636

Dear CouchDB Community,

last week, we announced the release of CouchDB versions 2.1.1 &
1.7.0/1.7.1 and marked them as CRITICAL security updates.

Today we are releasing detailed information about the security issues.

We expect all users to have updated already.

# Overview

## CVE-2017-12635

Due to differences in CouchDB’s Erlang-based JSON parser and JavaScript-based
JSON parser, it is possible to submit _users documents with duplicate keys for
`roles` used for access control within the database, including the special case
`_admin` role, that denotes administrative users. In combination with
`CVE-2017-12636` (Remote Code Execution), this can be used to give non-admin
users access to arbitrary shell commands on the server as the database system
user.

The JSON parser differences result in behaviour that if two `roles` keys
are available in the JSON, the second one will be used for authorising the
document write, but the first `roles` key is used for subsequent
authorization for the newly created user. By design, users can not assign
themselves roles. The vulnerability allows non-admin users to give
themselves admin privileges.

We addressed this issue by updating the way CouchDB parses JSON in
Erlang, mimicking the JavaScript behaviour of picking the last key, if
duplicates exist.

This issue was discovered by `Max Justicz` (https://mastodon.mit.edu/@maxj)

See also: Max’s own blog post about the issue and the motivation behind
his research: https://justi.cz/security/2017/11/14/couchdb-rce-npm.html

## CVE-2017-12636

CouchDB administrative users can configure the database server via HTTP(S). Some
of the configuration options include paths for operating system-level binaries
that are subsequently launched by CouchDB. This allows a CouchDB admin user to
execute arbitrary shell commands as the CouchDB user, including downloading
and executing scripts from the public internet.

This issue was discovered by `Joan Touzet` (http://www.atypical.net) of the
CouchDB Security team during the investigation of `CVE-2017-12635`.


# Details on CVE-2017-12635

CouchDB’s data exchange format is exclusively JSON. Internally, JSON is represented
as an Erlang proplist. That implementation detail leads to a nearly unique behaviour
in CouchDB when it comes to JSON parsing:: allowing JSON documents with multiple
keys of the same name.

CouchDB uses JavaScript-based authorisation functions for managing users’
access control. For example, to create a user, a document is inserted into the
special-case _users database. The user document must include a top level
key `roles` with a list of strings that gives users extra privileges.

By default, only admin users can set roles, ensuring users themselves can
not exceed their assigned privileges. In addition, it is possible to let users
sign up anonymously. In that scenario, it is even more important that
privilege-granting roles are not self-selected.

The JavaScript spec for JSON[1] with multiple keys requires parsers to pick the
last key they parse to be the one to end up in the JavaScript object constructed
from that JSON string.

[1]: https://www.ecma-international.org/ecma-262/5.1/

CouchDB internal and Erlang-level accessor functions pick the first available
key.

This difference led to multiple exploit scenarios:

1. via _users
2. via _replicator

In the case of the _users database, allowing duplicate keys allowed attackers
to submit a _users doc with two `roles` keys. The first one could include any
self-assigned roles, as the JavaScript validation function would only ever see
the second key. When authenticating users on subsequent requests, the `roles`
key was read from the Erlang-JSON representation and in that implementation
the first `roles` key was returned. That could now include any roles, including
the special case _admin role, giving users admin privileges.

In the case of the _replicator database, the authentication bypass occurs
because the CouchDB replicator assumes it is the only actor that can set the
`_replication_state` field of a replication document. The document validation
skips further authentication if that field has a value of `false`. The duplicate
keys bypass now allows users to set the `_replication_state` field to false to
enable arbitrary edits, and then allows to modify the user context (`userCtx`)
of the replication arbitrarily, which then can be used to insert documents into
any database. This includes _design documents which could hold further
validation and authentication functions that could be disabled that way.


# Details on CVE 2017-12636

CouchDB allows the setting of configuration variables via HTTP(S) or by
editing configuration files. Changing via HTTP(S) has the advantage of
avoiding a process restart. A number of CouchDB’s configuration settings
are file paths to executables that are dutifully executed by CouchDB
proper on startup or when a new config setting is provided via HTTP(S).

The config API is only available to admin users. Setting arbitrary executable
paths allows admins to set any executable through the use of the HTTP(S)
API. These executables will run in the scope of the operating system
user under which CouchDB runs. This includes read/write access to the
database files, and at least read access to its configuration files.

We have mitigated this attack-vector by implementing a blacklist of
configuration settings that can not be changed via HTTP(S) and require
shell access to modify.

A hard-coded blacklist has the downside of needing to be updated when newly
added configuration settings to CouchDB also need blacklisting. We opted
for this approach for reasons of expediency. In future, we’ll extend the
configuration system that the addition of configuration settings will
require explicit marking a variable to be safe for editing via HTTP(S).

In combination with CVE-2017-12635, this allows anonymous users to
gain shell access as the operating system user that CouchDB runs under.


# Am I impacted?

The easiest way to find out whether you have been targeted with
documents that include duplicate keys is to run this command to
check the _users database:

    curl -s 'admin:password@127.0.0.1:5984/_users/_all_docs?include_docs=true' | grep -E '"roles".+"roles"'

Analogous for _replicator:

    curl -s 'admin:password@127.0.0.1:5984/_users/_all_docs?include_docs=true' | grep -E ‘“_replication_state”.+"_replication_state"'


# Impact Assessment

Due to the severity of these issues and their combination, we have
delayed the release of this detailed information, and urged all users
to update to the latest releases.

If you still haven’t updated, here’s a short guide to asses whether the
vulnerabilities affect you. This is valid for all CouchDB 1.x and 2.x users
that aren’t on 2.1.1 or later or 1.7.0/1 or later.

Public CouchDB instances:
- you should already have updated to the new release.
- if you have enabled require_valid_user AND if you trust all your
   users with database admin & server shell access: there is no problem

Internal CouchDB instances:
- if you trust everyone on the network: no problem.
- if you have require_valid_user enabled AND if you trust all your
   users with database admin & server shell access: no problem
- if you have require_valid_user disabled AND if you trust all your
   users with database admin & server shell access: enable require_valid_user

Best
Jan
—