class Rack::Session::SmartCookie

Constants

BAD_DIGESTS
DEFAULT_DIGEST
SECRET_MIN_BYTESIZE
VERSION

Public Class Methods

new(app, options={}) click to toggle source
Calls superclass method
# File lib/rack/session/smart_cookie.rb, line 71
      def initialize(app, options={})
        options[:coder] ||= MessagePack.new
        unless options.key?(:hmac)
          options[:hmac] = OpenSSL::Digest(options.fetch(:digest, DEFAULT_DIGEST))
        end

        super

        if @secrets.any?
          hmac = options[:hmac].new # throwaway object for inspection purposes

          warn <<-MSG if BAD_DIGESTS.include?(hmac.name)
        SECURITY WARNING: You have elected to use an old and insecure message
        digest algorithm (#{hmac.class}).

        Such algorithms are generally considered to be effectively broken. It
        is strongly recommended that you elect to use a message digest
        algorithm from the SHA2 family: SHA224, SHA256, SHA384, or SHA512, or
        one of the derivatives such as SHA512/256. This will help prevent
        exploits that may be possible from crafted cookies.

        Called from: #{caller[0]}.
          MSG

          unless (SECRET_MIN_BYTESIZE .. hmac.block_length).cover?(@secrets.first.bytesize)
            show_caveat = hmac.digest_length > SECRET_MIN_BYTESIZE

            message = String.new(<<-MSG)
        SECURITY WARNING: You have provided a session secret with a sub-optimal
        byte size.

        It is strongly recommended that you select a secret at least #{SECRET_MIN_BYTESIZE} bytes
        long#{'*' if show_caveat}, but not longer than the block size (#{hmac.block_length} bytes) of the selected
        message digest algorithm (#{hmac.class}). This will help
        prevent exploits that may be possible from crafted cookies.
            MSG

            message << "\n        " \
              "* - Ideally, at least #{hmac.digest_length} bytes long.\n" if show_caveat

            message << "\n        " \
              "Called from: #{caller[0]}."

            warn message
          end
        end

        @digest_bytes = options[:digest_bytes]
      end

Private Instance Methods

generate_hmac(data, secret) click to toggle source
# File lib/rack/session/smart_cookie.rb, line 155
def generate_hmac(data, secret)
  digest = OpenSSL::HMAC.digest(@hmac.new, secret, data)
  Base64.encode(@digest_bytes ? digest.byteslice(0, @digest_bytes) : digest)
end
write_session(req, session_id, session, options) click to toggle source
# File lib/rack/session/smart_cookie.rb, line 143
def write_session(req, session_id, session, options)
  session = session.merge('session_id'=>session_id)
  bin_session_data = coder.encode(session)
  session_data = Base64.encode(bin_session_data)

  if @secrets.any?
    session_data << '.' << generate_hmac(bin_session_data, @secrets.first)
  end

  session_data
end