rack / rack-attack

Rack middleware for blocking & throttling
MIT License
5.56k stars 337 forks source link

Ruby 2.5 compatibility? #253

Closed waruboy closed 6 years ago

waruboy commented 6 years ago

Hello. Thank you for this gem. I use it on my project and it is great!

Recently I tried to update the project to ruby 2.5. Unfortunately I immediately get the following error:

NameError · uninitialized constant Redis::Store

Could this be related to: https://blog.bigbinary.com/2017/10/18/ruby-2.5-has-removed-top-level-constant-lookup.html ?

Complete stack:

vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy/redis_store_proxy.rb:8:in `handle?': uninitialized constant Redis::Store (NameError)
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy.rb:11:in `block in build'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy.rb:11:in `each'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy.rb:11:in `find'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy.rb:11:in `build'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/cache.rb:14:in `store='
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/cache.rb:8:in `initialize'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:104:in `new'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:104:in `cache'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/throttle.rb:17:in `cache'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack/throttle.rb:27:in `[]'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:89:in `block in throttled?'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:88:in `any?'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:88:in `throttled?'
    from vendor/bundle/ruby/2.5.0/gems/rack-attack-5.0.1/lib/rack/attack.rb:143:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb:36:in `block in call'
    from vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb:35:in `catch'
    from vendor/bundle/ruby/2.5.0/gems/warden-1.2.7/lib/warden/manager.rb:35:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/etag.rb:24:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/conditionalget.rb:25:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/head.rb:13:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/params_parser.rb:27:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/flash.rb:260:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/session/abstract/id.rb:225:in `context'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/session/abstract/id.rb:220:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-p3p-0.5.0/lib/rack-p3p.rb:11:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/cookies.rb:560:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/activerecord-4.2.10/lib/active_record/query_cache.rb:36:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/activerecord-4.2.10/lib/active_record/connection_adapters/abstract/connection_pool.rb:653:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/callbacks.rb:88:in `__run_callbacks__'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/callbacks.rb:778:in `_run_call_callbacks'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/callbacks.rb:27:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/lograge-0.3.4/lib/lograge/rails_ext/rack/logger.rb:15:in `call_app'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/rack/logger.rb:20:in `block in call'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/tagged_logging.rb:68:in `block in tagged'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/tagged_logging.rb:26:in `tagged'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/tagged_logging.rb:68:in `tagged'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/rack/logger.rb:20:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/request_store-1.3.2/lib/request_store/middleware.rb:9:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/request_id.rb:21:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/methodoverride.rb:22:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/runtime.rb:18:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-timeout-0.3.2/lib/rack/timeout/core.rb:125:in `block in call'
    from vendor/bundle/ruby/2.5.0/gems/rack-timeout-0.3.2/lib/rack/timeout/support/timeout.rb:19:in `timeout'
    from vendor/bundle/ruby/2.5.0/gems/rack-timeout-0.3.2/lib/rack/timeout/core.rb:124:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/static.rb:120:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-1.6.8/lib/rack/sendfile.rb:113:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/actionpack-4.2.10/lib/action_dispatch/middleware/ssl.rb:24:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/hirefire-resource-0.4.2/lib/hirefire/middleware.rb:41:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/engine.rb:518:in `call'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/application.rb:165:in `call'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/railtie.rb:194:in `public_send'
    from vendor/bundle/ruby/2.5.0/gems/railties-4.2.10/lib/rails/railtie.rb:194:in `method_missing'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:19:in `call'
    from vendor/bundle/ruby/2.5.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/middleware.rb:25:in `call'
    from vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-3.18.1.330/lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
    from vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/configuration.rb:224:in `call'
    from vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/server.rb:602:in `handle_request'
    from vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/server.rb:435:in `process_client'
    from vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/server.rb:299:in `block in run'
    from vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
grzuy commented 6 years ago

Hi,

Can you provide more detail on how are you configuring rack-attack's cache store?

Thanks!

waruboy commented 6 years ago

Hi! Thanks for responding.

I don't set anything for the cache store, so I guess it's using Rails.cache ? which is currently :file_store

Here is my whole initializer

# frozen_string_literal: true

module Rack
  # rack-attack gem configuration
  class Attack
    throttle("search", limit: 1, period: 1.second) do |req|
      "count" if req.path == "/api/v2/stores/search" && !Rails.env.test?
    end
  end
end
grzuy commented 6 years ago

I created a brand new test rails 4.2.10 app, using ruby 2.5.0, added rack-attack with the same config you provided and cannot reproduce the issue.

Can you provide the specific puma config you have? Thanks!

waruboy commented 6 years ago

Here's my config/puma.rb

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 1)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveSupport.on_load(:active_record) do
    ActiveRecord::Base.establish_connection
  end

  if defined?(Resque)
    Resque.redis = ENV["REDISTOGO_URL"] || "redis://127.0.0.1:6379"
  end
end

It was on heroku. I just noticed that this does not happen in my local dev machine, so perhaps it is combination of something in my production specific env and ruby 2.5.

Here are the ENV values:

RACK_ENV=production
WEB_CONCURRENCY=2
MAX_THREADS=2

Thanks again for looking up on this.

jeffblake commented 6 years ago

Subscribed.. same issue here w/ Ruby 2.5.

If I drop this section of code in the initializer, the apps works again:

  blocklist('fail2ban pentesters') do |req|
    # `filter` returns truthy value if request fails, or if it's from a previously banned IP
    # so the request is blocked
    Rack::Attack::Fail2Ban.filter("pentesters-#{req.ip}", maxretry: 3, findtime: 10.minutes, bantime: 1.week) do
      # The count for the IP is incremented if the return value is truthy
      CGI.unescape(req.query_string) =~ %r{/etc/passwd} ||
      req.path.include?('/etc/passwd') ||
      req.path.include?('wp-admin') ||
      req.path.include?('wp-login')

    end
  end

Full initializer:

Rails.application.middleware.insert 0, Rack::Attack
# if Rails.application.config.skylight.environments.include?(Rails.env.to_s)
#   Rails.application.middleware.insert_after Skylight::Middleware, Rack::Attack
# else
#   Rails.application.middleware.insert 0, Rack::Attack
# end
class Rack::Attack
  # your custom configuration...

  # Throttle public API requests
  throttle('req/ip', limit: 300, period: 5.minutes) do |req|
    req.ip if req.path.start_with?('/api/public')
  end

  # blocklist('fail2ban pentesters') do |req|
  #   # `filter` returns truthy value if request fails, or if it's from a previously banned IP
  #   # so the request is blocked
  #   Rack::Attack::Fail2Ban.filter("pentesters-#{req.ip}", maxretry: 3, findtime: 10.minutes, bantime: 1.week) do
  #     # The count for the IP is incremented if the return value is truthy
  #     CGI.unescape(req.query_string) =~ %r{/etc/passwd} ||
  #     req.path.include?('/etc/passwd') ||
  #     req.path.include?('wp-admin') ||
  #     req.path.include?('wp-login')
  #
  #   end
  # end

  self.throttled_response = -> (env) {
    retry_after = (env['rack.attack.match_data'] || {})[:period]
    [
      429,
      {'Content-Type' => 'application/json', 'Retry-After' => retry_after.to_s},
      [{type: :rate_limit_exceeded, message: "Throttle limit reached. Retry later."}.to_json]
    ]
  }

end
grzuy commented 6 years ago

@waruboy Still no luck reproducing the issue here.

Are you using resque and/or redis? Which versions?

Maybe you want to share Gemfile.lock :-)

waruboy commented 6 years ago

@grzuy Sorry for just replying. I tried to update other related gems but still the problem persist. Here is my Gemfile.lock

Btw if remove the && !Rails.env.test? part from the initializer, I observed the same error when running test (Rspec reqeust test). So it happened in my production and test env, but not in my dev env . A clue somewhere there perhaps?

GIT
  remote: git://github.com/bigcommerce/omniauth-bigcommerce.git
  revision: 82ee4772e2de5faecdd22c4e2f1ea3388954ea95
  specs:
    omniauth-bigcommerce (0.2.0)
      omniauth (~> 1.0)
      omniauth-oauth2 (~> 1.1)

GIT
  remote: git://github.com/rweng/jquery-datatables-rails.git
  revision: b39229cf5bfad1e6b08c8520a345b68a44ec0972
  specs:
    jquery-datatables-rails (3.2.0)
      actionpack (>= 3.1)
      jquery-rails
      railties (>= 3.1)
      sass-rails

GEM
  remote: https://rubygems.org/
  specs:
    CFPropertyList (2.3.5)
    actionmailer (4.2.10)
      actionpack (= 4.2.10)
      actionview (= 4.2.10)
      activejob (= 4.2.10)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 1.0, >= 1.0.5)
    actionpack (4.2.10)
      actionview (= 4.2.10)
      activesupport (= 4.2.10)
      rack (~> 1.6)
      rack-test (~> 0.6.2)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (4.2.10)
      activesupport (= 4.2.10)
      builder (~> 3.1)
      erubis (~> 2.7.0)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.3)
    activejob (4.2.10)
      activesupport (= 4.2.10)
      globalid (>= 0.3.0)
    activemodel (4.2.10)
      activesupport (= 4.2.10)
      builder (~> 3.1)
    activerecord (4.2.10)
      activemodel (= 4.2.10)
      activesupport (= 4.2.10)
      arel (~> 6.0)
    activeresource (4.0.0)
      activemodel (~> 4.0)
      activesupport (~> 4.0)
      rails-observers (~> 0.1.1)
    activesupport (4.2.10)
      i18n (~> 0.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    addressable (2.5.2)
      public_suffix (>= 2.0.2, < 4.0)
    arel (6.0.4)
    ast (2.3.0)
    bcrypt (3.1.11)
    benchmark-ips (2.7.2)
    best_in_place (3.0.3)
      actionpack (>= 3.2)
      railties (>= 3.2)
    better_errors (2.4.0)
      coderay (>= 1.0.0)
      erubi (>= 1.0.0)
      rack (>= 0.9.0)
    binding_of_caller (0.7.3)
      debug_inspector (>= 0.0.1)
    bitly (0.10.4)
      httparty (>= 0.7.6)
      multi_json (~> 1.3)
      oauth2 (>= 0.5.0, < 2.0)
    bootstrap-sass (2.0.0)
    bootstrap-will_paginate (0.0.10)
      will_paginate
    bugsnag (5.3.3)
    builder (3.2.3)
    bullet (5.6.1)
      activesupport (>= 3.0.0)
      uniform_notifier (~> 1.10.0)
    capybara (2.15.4)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (>= 1.3.3)
      rack (>= 1.0.0)
      rack-test (>= 0.5.4)
      xpath (~> 2.0)
    carrierwave (0.10.0)
      activemodel (>= 3.2.0)
      activesupport (>= 3.2.0)
      json (>= 1.7)
      mime-types (>= 1.16)
    carrierwave_direct (0.0.15)
      carrierwave
      fog
      uuidtools
    childprocess (0.8.0)
      ffi (~> 1.0, >= 1.0.11)
    climate_control (0.0.3)
      activesupport (>= 3.0)
    coderay (1.1.2)
    coffee-rails (4.2.2)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.12.2)
    colored (1.2)
    commonjs (0.2.7)
    concurrent-ruby (1.0.5)
    connection_pool (2.2.1)
    crack (0.4.3)
      safe_yaml (~> 1.0.0)
    crass (1.0.3)
    cri (2.10.1)
      colored (~> 1.2)
    database_cleaner (1.6.2)
    ddplugin (1.0.1)
    debug_inspector (0.0.3)
    declarative (0.0.9)
    declarative-option (0.1.0)
    derailed (0.1.0)
      derailed_benchmarks
    derailed_benchmarks (1.3.2)
      benchmark-ips (~> 2)
      get_process_mem (~> 0)
      heapy (~> 0)
      memory_profiler (~> 0)
      rack (>= 1)
      rake (> 10, < 13)
      thor (~> 0.19)
    devise (4.4.0)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 4.1.0, < 5.2)
      responders
      warden (~> 1.2.3)
    diff-lcs (1.3)
    docile (1.1.5)
    domain_name (0.5.20170404)
      unf (>= 0.0.5, < 1.0.0)
    email_spec (2.1.1)
      htmlentities (~> 4.3.3)
      launchy (~> 2.1)
      mail (~> 2.6)
    erubi (1.7.0)
    erubis (2.7.0)
    excon (0.57.1)
    execjs (2.7.0)
    factory_bot (4.8.2)
      activesupport (>= 3.0.0)
    factory_bot_rails (4.8.2)
      factory_bot (~> 4.8.2)
      railties (>= 3.0.0)
    faker (1.8.4)
      i18n (~> 0.5)
    faraday (0.9.2)
      multipart-post (>= 1.2, < 3)
    fastly (1.11.0)
    fastly-rails (0.8.0)
      fastly (~> 1.6)
      railties (> 2, < 6)
    ffi (1.9.18)
    figaro (1.1.0)
      thor (~> 0.14)
    fission (0.5.0)
      CFPropertyList (~> 2.2)
    fog (1.40.0)
      fog-aliyun (>= 0.1.0)
      fog-atmos
      fog-aws (>= 0.6.0)
      fog-brightbox (~> 0.4)
      fog-cloudatcost (~> 0.1.0)
      fog-core (~> 1.43)
      fog-digitalocean (>= 0.3.0)
      fog-dnsimple (~> 1.0)
      fog-dynect (~> 0.0.2)
      fog-ecloud (~> 0.1)
      fog-google (<= 0.1.0)
      fog-json
      fog-local
      fog-openstack
      fog-powerdns (>= 0.1.1)
      fog-profitbricks
      fog-rackspace
      fog-radosgw (>= 0.0.2)
      fog-riakcs
      fog-sakuracloud (>= 0.0.4)
      fog-serverlove
      fog-softlayer
      fog-storm_on_demand
      fog-terremark
      fog-vmfusion
      fog-voxel
      fog-vsphere (>= 0.4.0)
      fog-xenserver
      fog-xml (~> 0.1.1)
      ipaddress (~> 0.5)
      json (>= 1.8, < 2.0)
    fog-aliyun (0.1.0)
      fog-core (~> 1.27)
      fog-json (~> 1.0)
      ipaddress (~> 0.8)
      xml-simple (~> 1.1)
    fog-atmos (0.1.0)
      fog-core
      fog-xml
    fog-aws (1.4.0)
      fog-core (~> 1.38)
      fog-json (~> 1.0)
      fog-xml (~> 0.1)
      ipaddress (~> 0.8)
    fog-brightbox (0.11.0)
      fog-core (~> 1.22)
      fog-json
      inflecto (~> 0.0.2)
    fog-cloudatcost (0.1.2)
      fog-core (~> 1.36)
      fog-json (~> 1.0)
      fog-xml (~> 0.1)
      ipaddress (~> 0.8)
    fog-core (1.44.3)
      builder
      excon (~> 0.49)
      formatador (~> 0.2)
    fog-digitalocean (0.3.0)
      fog-core (~> 1.42)
      fog-json (>= 1.0)
      fog-xml (>= 0.1)
      ipaddress (>= 0.5)
    fog-dnsimple (1.0.0)
      fog-core (~> 1.38)
      fog-json (~> 1.0)
    fog-dynect (0.0.3)
      fog-core
      fog-json
      fog-xml
    fog-ecloud (0.3.0)
      fog-core
      fog-xml
    fog-google (0.1.0)
      fog-core
      fog-json
      fog-xml
    fog-json (1.0.2)
      fog-core (~> 1.0)
      multi_json (~> 1.10)
    fog-local (0.3.1)
      fog-core (~> 1.27)
    fog-openstack (0.1.21)
      fog-core (>= 1.40)
      fog-json (>= 1.0)
      ipaddress (>= 0.8)
    fog-powerdns (0.1.1)
      fog-core (~> 1.27)
      fog-json (~> 1.0)
      fog-xml (~> 0.1)
    fog-profitbricks (3.0.0)
      fog-core (~> 1.42)
      fog-json (~> 1.0)
    fog-rackspace (0.1.5)
      fog-core (>= 1.35)
      fog-json (>= 1.0)
      fog-xml (>= 0.1)
      ipaddress (>= 0.8)
    fog-radosgw (0.0.5)
      fog-core (>= 1.21.0)
      fog-json
      fog-xml (>= 0.0.1)
    fog-riakcs (0.1.0)
      fog-core
      fog-json
      fog-xml
    fog-sakuracloud (1.7.5)
      fog-core
      fog-json
    fog-serverlove (0.1.2)
      fog-core
      fog-json
    fog-softlayer (1.1.4)
      fog-core
      fog-json
    fog-storm_on_demand (0.1.1)
      fog-core
      fog-json
    fog-terremark (0.1.0)
      fog-core
      fog-xml
    fog-vmfusion (0.1.0)
      fission
      fog-core
    fog-voxel (0.1.0)
      fog-core
      fog-xml
    fog-vsphere (1.11.0)
      fog-core
      rbvmomi (~> 1.9)
    fog-xenserver (0.3.0)
      fog-core
      fog-xml
    fog-xml (0.1.3)
      fog-core
      nokogiri (>= 1.5.11, < 2.0.0)
    font-awesome-sass (4.2.2)
      sass (~> 3.2)
    formatador (0.2.5)
    geocoder (1.2.11)
    get_process_mem (0.2.1)
    globalid (0.4.1)
      activesupport (>= 4.2.0)
    gon (6.2.0)
      actionpack (>= 3.0)
      multi_json
      request_store (>= 1.0)
    google-api-client (0.10.3)
      addressable (~> 2.3)
      googleauth (~> 0.5)
      httpclient (~> 2.7)
      hurley (~> 0.1)
      memoist (~> 0.11)
      mime-types (>= 1.6)
      representable (~> 3.0)
      retriable (>= 2.0, < 4.0)
    google_drive (2.1.2)
      google-api-client (>= 0.9.0, < 1.0.0)
      googleauth (>= 0.5.0, < 1.0.0)
      nokogiri (>= 1.5.3, < 2.0.0)
    googleauth (0.5.1)
      faraday (~> 0.9)
      jwt (~> 1.4)
      logging (~> 2.0)
      memoist (~> 0.12)
      multi_json (~> 1.11)
      os (~> 0.9)
      signet (~> 0.7)
    growl (1.0.3)
    haml (4.0.7)
      tilt
    haml-rails (0.9.0)
      actionpack (>= 4.0.1)
      activesupport (>= 4.0.1)
      haml (>= 4.0.6, < 5.0)
      html2haml (>= 1.0.1)
      railties (>= 4.0.1)
    hamster (3.0.0)
      concurrent-ruby (~> 1.0)
    hashdiff (0.3.7)
    hashie (3.4.0)
    heapy (0.1.3)
    heroku-api (0.3.23)
      excon (~> 0.44)
      multi_json (~> 1.8)
    hike (1.2.3)
    hirefire-resource (0.4.2)
    html2haml (2.2.0)
      erubis (~> 2.7.0)
      haml (>= 4.0, < 6)
      nokogiri (>= 1.6.0)
      ruby_parser (~> 3.5)
    htmlentities (4.3.4)
    http-cookie (1.0.3)
      domain_name (~> 0.5)
    httparty (0.14.0)
      multi_xml (>= 0.5.2)
    httpclient (2.8.3)
    hurley (0.2)
    i18n (0.9.3)
      concurrent-ruby (~> 1.0)
    iconv (1.0.5)
    immutable-struct (2.2.2)
    inflecto (0.0.2)
    intercom (2.4.4)
      json (~> 1.8)
    intercom-rails (0.2.27)
      activesupport (> 3.0)
    ipaddress (0.8.3)
    jquery-rails (4.3.1)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    jquery-ui-rails (4.1.2)
      railties (>= 3.1.0)
    json (1.8.6)
    jwt (1.5.4)
    keen (1.1.1)
      addressable (~> 2.5)
      multi_json (~> 1.12)
    kramdown (1.14.0)
    launchy (2.4.3)
      addressable (~> 2.3)
    less (2.3.3)
      commonjs (~> 0.2.6)
    less-rails (2.3.3)
      actionpack (>= 3.1)
      less (~> 2.3.1)
    less-rails-bootstrap (2.3.3)
      less-rails (~> 2.3.1)
    letter_opener (1.4.1)
      launchy (~> 2.2)
    libnotify (0.9.1)
      ffi (>= 1.0.11)
    little-plugger (1.1.4)
    logging (2.2.2)
      little-plugger (~> 1.1)
      multi_json (~> 1.10)
    lograge (0.3.4)
      actionpack (>= 3)
      activesupport (>= 3)
      railties (>= 3)
    loofah (2.1.1)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.0)
      mini_mime (>= 0.1.1)
    memoist (0.15.0)
    memory_profiler (0.9.8)
    method_source (0.9.0)
    mime-types (3.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2016.0521)
    mini_mime (1.0.0)
    mini_portile2 (2.3.0)
    minitest (5.11.1)
    mixpanel-ruby (2.0.1)
    mono_logger (1.1.0)
    multi_json (1.13.1)
    multi_xml (0.5.5)
    multipart-post (2.0.0)
    nanoc (4.8.11)
      addressable (~> 2.5)
      cri (~> 2.8)
      ddplugin (~> 1.0)
      hamster (~> 3.0)
      ref (~> 2.0)
      slow_enumerator_tools (~> 1.0)
    netrc (0.11.0)
    newrelic_rpm (3.18.1.330)
    nokogiri (1.8.1)
      mini_portile2 (~> 2.3.0)
    oauth2 (0.9.4)
      faraday (>= 0.8, < 0.10)
      jwt (~> 1.0)
      multi_json (~> 1.3)
      multi_xml (~> 0.5)
      rack (~> 1.2)
    oj (3.2.0)
    omniauth (1.2.2)
      hashie (>= 1.2, < 4)
      rack (~> 1.0)
    omniauth-oauth2 (1.1.2)
      faraday (>= 0.8, < 0.10)
      multi_json (~> 1.3)
      oauth2 (~> 0.9.3)
      omniauth (~> 1.2)
    omniauth-shopify-oauth2 (1.1.0)
      omniauth-oauth2 (~> 1.1.0)
    orm_adapter (0.5.0)
    os (0.9.6)
    parallel (1.12.0)
    parser (2.4.0.0)
      ast (~> 2.2)
    pg (0.18.1)
    pghero (0.1.10)
      activerecord
    pluck_to_hash (1.0.0)
      activerecord (>= 4.0.2)
      activesupport (>= 4.0.2)
    powerpack (0.1.1)
    pry (0.11.3)
      coderay (~> 1.1.0)
      method_source (~> 0.9.0)
    pry-rails (0.3.6)
      pry (>= 0.10.4)
    public_suffix (3.0.1)
    puma (3.11.2)
    rabl (0.11.6)
      activesupport (>= 2.3.14)
    rack (1.6.8)
    rack-attack (5.0.1)
      rack
    rack-p3p (0.5.0)
      rack (>= 1.0.1)
    rack-protection (1.5.3)
      rack
    rack-proxy (0.5.17)
      rack
    rack-reverse-proxy (0.11.0)
      rack (>= 1.0.0)
      rack-proxy (~> 0.5, >= 0.5.14)
    rack-test (0.6.3)
      rack (>= 1.0)
    rack-timeout (0.3.2)
    rails (4.2.10)
      actionmailer (= 4.2.10)
      actionpack (= 4.2.10)
      actionview (= 4.2.10)
      activejob (= 4.2.10)
      activemodel (= 4.2.10)
      activerecord (= 4.2.10)
      activesupport (= 4.2.10)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.2.10)
      sprockets-rails
    rails-deprecated_sanitizer (1.0.3)
      activesupport (>= 4.2.0.alpha)
    rails-dom-testing (1.0.9)
      activesupport (>= 4.2.0, < 5.0)
      nokogiri (~> 1.6)
      rails-deprecated_sanitizer (>= 1.0.1)
    rails-html-sanitizer (1.0.3)
      loofah (~> 2.0)
    rails-observers (0.1.5)
      activemodel (>= 4.0)
    rails_12factor (0.0.3)
      rails_serve_static_assets
      rails_stdout_logging
    rails_serve_static_assets (0.0.4)
    rails_stdout_logging (0.0.3)
    railties (4.2.10)
      actionpack (= 4.2.10)
      activesupport (= 4.2.10)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    rainbow (2.2.2)
      rake
    rake (12.3.0)
    rb-fsevent (0.9.1)
    rb-inotify (0.8.8)
      ffi (>= 0.5.0)
    rbvmomi (1.11.3)
      builder (~> 3.0)
      json (>= 1.8)
      nokogiri (~> 1.5)
      trollop (~> 2.1)
    redis (3.3.5)
    redis-namespace (1.6.0)
      redis (>= 3.0.4)
    ref (2.0.0)
    representable (3.0.4)
      declarative (< 0.1.0)
      declarative-option (< 0.2.0)
      uber (< 0.2.0)
    request_store (1.3.2)
    responders (2.4.0)
      actionpack (>= 4.2.0, < 5.3)
      railties (>= 4.2.0, < 5.3)
    resque (1.27.4)
      mono_logger (~> 1.0)
      multi_json (~> 1.0)
      redis-namespace (~> 1.3)
      sinatra (>= 0.9.2)
      vegas (~> 0.1.2)
    resque-status (0.5.0)
      resque (~> 1.19)
    rest-client (2.0.2)
      http-cookie (>= 1.0.2, < 2.0)
      mime-types (>= 1.16, < 4.0)
      netrc (~> 0.8)
    retriable (3.0.2)
    rspec-core (3.7.1)
      rspec-support (~> 3.7.0)
    rspec-expectations (3.7.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.7.0)
    rspec-mocks (3.7.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.7.0)
    rspec-rails (3.7.2)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec-core (~> 3.7.0)
      rspec-expectations (~> 3.7.0)
      rspec-mocks (~> 3.7.0)
      rspec-support (~> 3.7.0)
    rspec-support (3.7.0)
    rubocop (0.51.0)
      parallel (~> 1.10)
      parser (>= 2.3.3.1, < 3.0)
      powerpack (~> 0.1)
      rainbow (>= 2.2.2, < 3.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (~> 1.0, >= 1.0.1)
    ruby-progressbar (1.9.0)
    ruby_parser (3.9.0)
      sexp_processor (~> 4.1)
    rubyzip (1.2.1)
    safe_yaml (1.0.4)
    sass (3.2.19)
    sass-rails (4.0.5)
      railties (>= 4.0.0, < 5.0)
      sass (~> 3.2.2)
      sprockets (~> 2.8, < 3.0)
      sprockets-rails (~> 2.0)
    select2-rails (3.5.9.3)
      thor (~> 0.14)
    selenium-webdriver (2.43.0)
      childprocess (~> 0.5)
      multi_json (~> 1.0)
      rubyzip (~> 1.0)
      websocket (~> 1.0)
    sexp_processor (4.9.0)
    shopify_api (3.0.3)
      activeresource (>= 3.0.0)
      thor (>= 0.14.4)
    shopify_app (4.2.2)
      less-rails-bootstrap (~> 2.0)
      omniauth-shopify-oauth2 (= 1.1.0)
      rails (>= 3.1, < 5.0)
      shopify_api (~> 3.0.0)
    shoulda-matchers (3.1.2)
      activesupport (>= 4.0.0)
    sidekiq (4.2.10)
      concurrent-ruby (~> 1.0)
      connection_pool (~> 2.2, >= 2.2.0)
      rack-protection (>= 1.5.0)
      redis (~> 3.2, >= 3.2.1)
    sidekiq_status (1.2.0)
      sidekiq (>= 3.3, < 5)
    signet (0.7.3)
      addressable (~> 2.3)
      faraday (~> 0.9)
      jwt (~> 1.5)
      multi_json (~> 1.10)
    simple_abs (0.0.2)
    simple_form (3.5.0)
      actionpack (> 4, < 5.2)
      activemodel (> 4, < 5.2)
    simplecov (0.15.1)
      docile (~> 1.1.0)
      json (>= 1.8, < 3)
      simplecov-html (~> 0.10.0)
    simplecov-html (0.10.2)
    sinatra (1.4.8)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    slow_enumerator_tools (1.1.0)
    smarter_csv (1.0.19)
    sprockets (2.12.4)
      hike (~> 1.2)
      multi_json (~> 1.0)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    sprockets-rails (2.3.3)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      sprockets (>= 2.8, < 4.0)
    strip_attributes (1.8.0)
      activemodel (>= 3.0, < 6.0)
    stripe (3.3.2)
      faraday (~> 0.9)
    thor (0.20.0)
    thread_safe (0.3.6)
    tilt (1.4.1)
    timecop (0.9.1)
    traceroute (0.5.0)
      rails (>= 3.0.0)
    trollop (2.1.2)
    tzinfo (1.2.4)
      thread_safe (~> 0.1)
    uber (0.1.0)
    uglifier (2.7.1)
      execjs (>= 0.3.0)
      json (>= 1.8.0)
    unf (0.1.4)
      unf_ext
    unf_ext (0.0.7.4)
    unicode-display_width (1.3.0)
    uniform_notifier (1.10.0)
    uuidtools (2.1.5)
    vcr (3.0.3)
    vegas (0.1.11)
      rack (>= 1.0.0)
    warden (1.2.7)
      rack (>= 1.0)
    web-console (2.3.0)
      activemodel (>= 4.0)
      binding_of_caller (>= 0.7.2)
      railties (>= 4.0)
      sprockets-rails (>= 2.0, < 4.0)
    webmock (3.1.0)
      addressable (>= 2.3.6)
      crack (>= 0.3.2)
      hashdiff
    websocket (1.2.4)
    will_paginate (3.0.7)
    xml-simple (1.1.5)
    xmlrpc (0.2.1)
    xpath (2.1.0)
      nokogiri (~> 1.3)

PLATFORMS
  ruby

DEPENDENCIES
  actionpack
  addressable
  best_in_place
  better_errors (>= 0.3.2)
  binding_of_caller (>= 0.6.8)
  bitly
  bootstrap-sass (= 2.0.0)
  bootstrap-will_paginate
  bugsnag
  bullet
  capybara (>= 2.4.3)
  carrierwave_direct
  climate_control
  coffee-rails (~> 4.2.0)
  database_cleaner (>= 1.3.0)
  derailed
  devise (~> 4.4.0)
  email_spec (>= 1.2.1)
  factory_bot_rails
  faker (~> 1.8.4)
  fastly-rails (~> 0.4)
  figaro (>= 0.5.3)
  font-awesome-sass (~> 4.2.0)
  geocoder
  gon
  google_drive (~> 2.1.2)
  growl (= 1.0.3)
  haml
  haml-rails (>= 0.3.4)
  heroku-api
  hirefire-resource
  iconv
  immutable-struct (~> 2.2.2)
  intercom (~> 2.4.3)
  intercom-rails (~> 0.2.24)
  jquery-datatables-rails!
  jquery-rails
  jquery-ui-rails
  keen (~> 1.1.0)
  kramdown
  launchy (>= 2.4.3)
  letter_opener
  libnotify
  lograge
  mixpanel-ruby
  nanoc
  newrelic_rpm (~> 3.11)
  nokogiri
  oj
  omniauth-bigcommerce!
  omniauth-oauth2
  omniauth-shopify-oauth2
  pg
  pghero
  pluck_to_hash
  pry-rails
  puma
  rabl
  rack-attack (= 5.0.1)
  rack-p3p
  rack-reverse-proxy
  rack-timeout
  rails (~> 4.2.8)
  rails-observers
  rails_12factor
  rb-fsevent (= 0.9.1)
  rb-inotify (~> 0.8.8)
  resque
  resque-status
  rest-client (~> 2.0.2)
  rspec-rails (~> 3.6)
  rubocop
  sass (~> 3.2.0)
  sass-rails (~> 4.0.0)
  select2-rails
  selenium-webdriver (~> 2.43.0)
  shopify_app (~> 4.2.0)
  shoulda-matchers
  sidekiq
  sidekiq_status
  simple_abs
  simple_form (~> 3.3)
  simplecov
  smarter_csv
  strip_attributes
  stripe
  timecop
  traceroute
  uglifier (>= 1.0.3)
  vcr
  web-console (~> 2.0)
  webmock
  will_paginate
  xmlrpc

RUBY VERSION
   ruby 2.5.0p0

BUNDLED WITH
   1.16.1
grzuy commented 6 years ago

@waruboy Thanks for sharing.

I put together brand new test rails app to attempt reproduce your issue but wasn't able. See https://github.com/grzuy/rails_test_app_4_2_10.

jeffblake commented 6 years ago

@waruboy Do you have a top level constant called Store ? E.g. an ActiveRecord model or similar?

I noticed in a previous version of ruby, I would get a ton of warnings, something like, IIRC, "top level constant Store referenced..." when rack attack was really looking for Redis::Store. Then it broke with this ruby. I don't need my Store model anymore, so I deleted it, tried Rack-attack again, and all is well now. Related? Possibly...

waruboy commented 6 years ago

@jeffblake ! I do have a model named "Store". Let me check

waruboy commented 6 years ago

yes, on my current production log I had similar warning like @jeffblake

Jan 26 01:28:31  /app/vendor/bundle/ruby/2.4.0/gems/rack-attack-5.0.1/lib/rack/attack/store_proxy/redis_store_proxy.rb:8: warning: toplevel constant Store referenced by Redis::Store 

unfortunately it's not possible for me to delete Store model. I tried to add store model to the test app but still not able to reproduce the issue... Might be related to why it works on my dev env

https://github.com/grzuy/rails_test_app_4_2_10/pull/1

waruboy commented 6 years ago

@grzuy ah got it. the test app miss this part:

# In config/application.rb
config.middleware.use Rack::Attack

now if you use this branch you can reproduce the error https://github.com/grzuy/rails_test_app_4_2_10/pull/1

waruboy commented 6 years ago

it also reproduce the way it does not happen on dev, but happens on test and production Rails.env

grzuy commented 6 years ago

Nice job! Thanks both @waruboy and @jeffblake for helping reproduce the issue. I'll let you know when i have more insights on why it's happening.

waruboy commented 6 years ago

@grzuy thanks for looking this up!

grzuy commented 6 years ago

Quick update: There is a PR that fixes this issue. I am waiting for a code review.

waruboy commented 6 years ago

Kinda amazing it goes up to ruby-lang bug

grzuy commented 6 years ago

Yup!

Thanks again for helping reproduce the issue in the first place.

grzuy commented 6 years ago

Fix for this has been released in v5.1.0.

waruboy commented 6 years ago

@grzuy thank you very much~~