Rubysec

Providing security resources for the Ruby community.
Follow us @rubysec or email us via info at rubysec.com

Advisory Archive

Back

---
gem: actionpack
date: 2016-01-25
url: https://groups.google.com/forum/#!topic/rubyonrails-security/ANv0HDHEC3k
cve: 2015-7576
title: Timing attack vulnerability in basic authentication in Action Controller.
description: |
  There is a timing attack vulnerability in the basic authentication support
  in Action Controller. This vulnerability has been assigned the CVE
  identifier CVE-2015-7576.

  Versions Affected:  All.
  Not affected:       None.
  Fixed Versions:     5.0.0.beta1.1, 4.2.5.1, 4.1.14.1, 3.2.22.1

  Impact
  ------
  Due to the way that Action Controller compares user names and passwords in
  basic authentication authorization code, it is possible for an attacker to
  analyze the time taken by a response and intuit the password.

  For example, this string comparison:

    "foo" == "bar"

  is possibly faster than this comparison:

    "foo" == "fo1"

  Attackers can use this information to attempt to guess the username and
  password used in the basic authentication system.

  You can tell you application is vulnerable to this attack by looking for
  `http_basic_authenticate_with` method calls in your application.

  All users running an affected release should either upgrade or use one of
  the workarounds immediately.

  Releases
  --------
  The FIXED releases are available at the normal locations.

  Workarounds
  -----------
  If you can't upgrade, please use the following monkey patch in an initializer
  that is loaded before your application:

  ```
  $ cat config/initializers/basic_auth_fix.rb
  module ActiveSupport
    module SecurityUtils
      def secure_compare(a, b)
        return false unless a.bytesize == b.bytesize

        l = a.unpack "C#{a.bytesize}"

        res = 0
        b.each_byte { |byte| res |= byte ^ l.shift }
        res == 0
      end
      module_function :secure_compare

      def variable_size_secure_compare(a, b)
        secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
      end
      module_function :variable_size_secure_compare
    end
  end

  module ActionController
    class Base
      def self.http_basic_authenticate_with(options = {})
        before_action(options.except(:name, :password, :realm)) do
          authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
            # This comparison uses & so that it doesn't short circuit and
            # uses `variable_size_secure_compare` so that length information
            # isn't leaked.
            ActiveSupport::SecurityUtils.variable_size_secure_compare(name, options[:name]) &
              ActiveSupport::SecurityUtils.variable_size_secure_compare(password, options[:password])
          end
        end
      end
    end
  end
  ```


  Patches
  -------
  To aid users who aren't able to upgrade immediately we have provided patches for
  the two supported release series. They are in git-am format and consist of a
  single changeset.

  * 4-1-basic_auth.patch - Patch for 4.1 series
  * 4-2-basic_auth.patch - Patch for 4.2 series
  * 5-0-basic_auth.patch - Patch for 5.0 series

  Please note that only the 4.1.x and 4.2.x series are supported at present. Users
  of earlier unsupported releases are advised to upgrade as soon as possible as we
  cannot guarantee the continued availability of security fixes for unsupported
  releases.

  Credits
  -------

  Thank you to Daniel Waterworth for reporting the problem and working with us to
  fix it.
patched_versions:
- ">= 5.0.0.beta1.1"
- "~> 4.2.5, >= 4.2.5.1"
- "~> 4.1.14, >= 4.1.14.1"
- "~> 3.2.22.1"