201705-01

Session fixation issue and authentication bypass in the authcrypt module

Background

In the previous SSPSA 201703-01 advisory, a constant time comparison function was introduced to avoid timing side-channel attacks when evaluating the authentication token tied to a session (which avoids session fixation attacks), and also when authenticating with the authcrypt module and using passwords hashed with the crypt() algorithm used in htpasswd files.

Description

The countermeasure to avoid this timing side-channel attacks consisted on the introduction of the SimpleSAML\Utils\Crypto::secureCompare() function. However, an issue in the implementation of this function introduced another vulnerability, as the output of the function was always true for strings with equal length, regardless of their contents, when running a version of PHP older than 5.6.

The issue was due to improper conversion to an integer of individual bytes in both strings, right before applying the XOR operator to them (^). In PHP, the XOR operation applied to strings (or characters) returns always an empty string, which was then converted to numerical 0 before applying a bitwise OR operation. This implies the result of the constant time comparison was always 0, making the function return the boolean true even if the contents of the two strings were completely different.

Strings with different length were not affected, as an specific check for that condition exists in the function.

Similarly, those running a version of PHP equal or newer than 5.6 were not affected, since in their case the function acts as a simple wrapper to hash_equals().

Affected versions

All SimpleSAMLphp versions before and including 1.14.13.

Impact

The issue described here has a critical impact, as it runs the affected function useless. As such, the session validation mechanism, consisting on the check for an authentication cookie whose value must be equal to an identifier held in the session's contents, is also useless, opening for session fixation attacks under certain circumstances.

In the same way, authentication with the authcrypt module is also affected by this issue. By exploiting it, an attacker can authenticate with any account and a random password, provided that the original password is stored in an htpasswd file and hashed using the crypt() algorithm. While this is even more critical than a session fixation attack, the crypt() algorithm has been considered insecure for many years now, and even without this particular issue it would be possible to exploit it to gain unauthorized access. Therefore, the fix for the issue described here does not make the use of this algorithm secure, and it should be avoided in any case.

Resolution

Upgrade to the latest version.

Credit

This security issue was discovered on May 5th of 2017 by Jaime Pérez Crespo, and reported on the same day by Matt Schwager.