UPDATE: 2011-10-06

Unfortunately, we discovered a problem with the brute force fix that could lead to incorrect authentication failures. The problem was most evident in multi-brick environments, but could occur in any environment with more than one open-ils.auth child processing authentication requests. Consequently, we have released updated versions of the security fix releases, along with an updated version of the 2.1.0 release; the only difference in these tarballs is an updated version of oils_auth.c. The names of the releases are as follows and can be downloaded from the Evergreen downloads page as usual:

2.1.0a

2.0.10a

1.6.1.9a

Sites that have not yet upgraded to the announced security release are advised to upgrade to the “a” version of the release. Sites that have upgraded to the announced security release are advised to simply replace the oils_auth.so shared library, as described in the comment to this post by Dan Scott, using the “a” version of the release. The staff clients provided for the security release will continue to work with the fixed “a” version of the release.

Original security release announcement

Today, the Evergreen development team released Evergreen 2.0.10 and 1.6.1.9 – available from the downloads page -to address several security vulnerabilities and a handful of bug fixes. This post discusses the security vulnerabilities. If you are running Evergreen in production today, we encourage you to upgrade your Evergreen system to 1.6.1.9 or 2.0.10 as soon as possible.

Summary of issues fixed in 2.0.10 and 1.6.1.9

These releases include some protection against brute force guessing of weak passwords, such as four digit pins.

A running count of incorrect login attempts for a given user is maintained. After ten incorrect attempts, all attempts to login as that user will fail until the counter resets. By default, the counter resets after 90 seconds. Both the counter and the number of incorrect passwords are configurable. This change requires no client-side changes.

This release also includes a change which prevents the re-use of an authentication seed to obtain more than one authentication token. This change required a single client-side change where the staff client was inadvertently re-using a seed legitimately.

Additional issues fixed in 2.0.10

On the patron visible front there is a change to the OPAC to require that the user’s current password be provided before changes to username or email address can be made. This prevents someone who gains access to another user’s account, say due to a public or otherwise shared computer, from changing the email address and requesting a password reset. The username change requiring the user’s password helps keep someone from being “locked out” of their account because someone changed their username without the user knowing.

To continue on the password related fixes there is the removal of the password from the login screen after it is no longer needed. This prevents malicious code injected into the staff client from obtaining the password by pulling it out of the password entry box in plain text. As this code is contained 100% within the local staff client a client update is required.

Technical details: fixes in 2.0.10 and 1.6.1.9

The most significant vulnerability that has been addressed was the ability to brute force passwords. The authentication functions, available to the world via HTTP/HTTPS, have been given protection against repeated attempts to guess passwords. After a configurable number of failed login attempts each within a configurable time span from the previous failed attempt the system will treat all attempts as failures, even if they are otherwise valid and correct. The default is 10 attempts with 90 seconds between attempts. The system will unlock after the time between attempts has expired. This can be installed server-side without any client side changes.

Related to brute forcing of passwords is password replay attempts. If you can grab the auth.complete call within the auth seed’s validity period you can re-send the auth.complete data and get a new authtoken, without needing to know the seed or password. To protect against this the auth seeds are rendered invalid after a single use (successful or not). This requires a single client side change to cover the case where the client thinks it has a registered workstation and the server disagrees. In that case the client was, in effect, performing a replay attack as part of normal operations.

3 thoughts on “Evergreen security releases: 2.0.10 and 1.6.1.9”

To address the worst of the vulnerabilities – the potential brute-forcing of passwords – it is possible to update just the oils_auth.so library on a live production system without having to go through a complete install and staff client update process and without having to stop and start all services. The process is as follows:

Optionally, you can also add the new <auth_limits> section to the <open-ils.auth> settings in /openils/conf/opensrf.xml if you want to specify non-default values. If so, then you will also need to restart the opensrf.settings service before restarting the OpenSRF C services.

One observation regarding the fix for brute force password guessing — we discovered the hard way that if there is a SIP2 device connecting to the Evergreen database that is configured with the wrong password for the user account it uses to authenticate, repeated login attempts by the device can result in quickly locking out that account. This can be mitigated by assigning a separate user account for each distinct SIP service (so that say, a misconfiguration for your PC reservation system doesn’t lock out e-resource authorization), by monitoring the logs for excessive failed authentication attempts after applying the security update, and, until the offending device is found, by setting the block_count parameter to a higher value on the application server(s) that are providing authentication for SIP2 service.

To follow up on Dan’s comment, note that /openils/lib/oils_auth.so is normally a symbolic link to oils_auth.so.2.0.0 (or oils_auth.so.0.0.0 in the case of 1.6.1.x). When applying Dan’s fix procedure, make sure that the final result has all versions of the file name oils_auth.so[.*] pointing to the same shared object.