neverpanic.de

CVE-2015-0842, CVE-2015-0843 in yubiserver

| Comments

Back in March 2015, I reported a security issue in Yubiserver, a small specialized HTTP server to verify HOTP/OATH tokens generated by Yubico’s Yubikeys. I’m publishing the details for reference.

I was looking for a new Yubikey validation server and, given its small size, decided to code review any candidates due to their small size. While looking at yubiserve, I found security issues in the code.

CVE-2015-0842

CVE-2015-0842 is an SQL injection issue. Yubiserver’s database backend is SQLite. User input is not added to prepared statements using sqlite3_bind_text, but instead uses sprintf(3) without any escaping. This affects the first 12 bytes of a Yubico OTP in OTP mode in modhex encoding (although the encoding will be skipped if non-modhex characters are encountered). Because the attacker is limited to 12 characters inside the WHERE clause of SELECT query the attack potential is small.

A similar issue affects the id parameter that is used to select a key for the HMAC that protects the response, with the exception that only a length restriction on the whole request exists. Again, this injection happens in a SELECT query. While an attacker can escape the quoting and add arbitrary SQL in the WHERE clause, the possibilities for exploitation are limited: INSERT and DELETE statements cannot be used in subqueries and separating an additional query using a semicolon does not work due to the use of sqlite3_prepare_v2 and sqlite3_step over sqlite3_exec.

The vulnerability can possibly be used to extract secret keys from the database using subqueries. This may be limited by the length limit on queries that can be executed. A proof of concept that tells us whether a secret key of a yubikey starts with “ab” would be:

curl \
	$'http://localhost:port/wsapi/2.0/verify?otp=a&id=1\'\tAND\t(SELECT\taeskey\tFROM\tyubikeys)\tLIKE\t"ab%";--'

CVE-2015-0843

CVE-2015-0843 covers multiple buffer overflows due to extensive use of sprintf(3) without range checks. All inputs that end up in queries, log messages or are sent back in the response are affected.

Denial of service is trivial by sending long inputs:

curl \
	"http://localhost:port/wsapi/2.0/verify?otp=x&id=$(openssl rand -hex 512)"

On most Linux distributions, this triggers the stack canary and kills the process. Further exploitation may be possible, but has not been attempted.

Timeline

  • 2015-03-31: Issue reported to the Debian security team, who agree to forward it upstream.
  • 2015-05-28: Debian security team confirms they are still waiting for patches and agree to follow-up upstream.
  • 2015-05-29: Upstream releases 0.6 with patches for the vulnerabilities.
  • 2015-10-02: Debian security team confirms CVE-2015-0842 and CVE-2015-0843 are assigned to these issues and patches have not been backported to wheezy and jessie.
  • 2017-02-13: Public release.

Mitigations

Updating to 0.6 fixes both vulnerabilities. The SQL injections no longer occur because the code uses prepared statements and parameter binding. The buffer overflows have been mitigated by switching to snprintf(3) and providing appropriate sizes, truncating the data if it would overflow the buffer.

The update to 0.6 does not include functional changes, so upgrading should be safe.

Recommendations

Switch to a server implementation that does not suffer from buffer overflows by language design. For example:

Comments

Please enable JavaScript to view comments. Note that comments are provided by a local instance of Isso. No data is sent to third party servers. For more information, see the privacy policy.