Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby 2.5 compatibility? #253

Closed
waruboy opened this issue Jan 8, 2018 · 20 comments · Fixed by #271
Closed

Ruby 2.5 compatibility? #253

waruboy opened this issue Jan 8, 2018 · 20 comments · Fixed by #271

Comments

@waruboy
Copy link

waruboy commented Jan 8, 2018

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
Copy link
Collaborator

grzuy commented Jan 18, 2018

Hi,

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

Thanks!

@waruboy
Copy link
Author

waruboy commented Jan 19, 2018

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
Copy link
Collaborator

grzuy commented Jan 19, 2018

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
Copy link
Author

waruboy commented Jan 20, 2018

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
Copy link

jeffblake commented Jan 22, 2018

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
Copy link
Collaborator

grzuy commented Jan 23, 2018

@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
Copy link
Author

waruboy commented Jan 25, 2018

@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
Copy link
Collaborator

grzuy commented Jan 25, 2018

@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
Copy link

jeffblake commented Jan 26, 2018

@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
Copy link
Author

waruboy commented Jan 26, 2018

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

@waruboy
Copy link
Author

waruboy commented Jan 26, 2018

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
Copy link
Author

waruboy commented Jan 26, 2018

@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
Copy link
Author

waruboy commented Jan 26, 2018

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

@grzuy
Copy link
Collaborator

grzuy commented Jan 26, 2018

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
Copy link
Author

waruboy commented Jan 27, 2018

@grzuy thanks for looking this up!

grzuy added a commit to grzuy/rack-attack that referenced this issue Jan 29, 2018
Anyone using:
  * ruby 2.5
  * redis
  * rack-attack without redis-store and using at least one throttle
  * having a toplevel class named Store

will hit this ruby 2.5 bug https://bugs.ruby-lang.org/issues/14407

That's because of the following buggy behavior of 'defined?' under ruby
2.5:

```
$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

$ irb
> class Redis
> end
=> nil
> class Store
> end
=> nil
> defined?(::Redis::Store)
=> "constant"
> ::Redis::Store
  NameError (uninitialized constant Redis::Store
    Did you mean?  Store)
```
grzuy added a commit to grzuy/rack-attack that referenced this issue Jan 29, 2018
'defined?' is buggy in ruby 2.5.0, which under certain circumstances
users using rack-attack can hit. See issue rack#253.

I reported (https://bugs.ruby-lang.org/issues/14407) and
fixed (ruby/ruby#1800) the issue in
ruby already, but i guess i would take some time before there's
a new ruby release including that fix.

So for now we would need to circumvent this bug by using
'const_defined?' instead of 'defined?' for this particular case.

More details:

Anyone using:
  * ruby 2.5.0
  * redis
  * rack-attack without redis-store and using at least one throttle
  * having a toplevel class named Store

will hit this ruby 2.5.0 bug https://bugs.ruby-lang.org/issues/14407

That's because of the following buggy behavior of 'defined?' under ruby
2.5:

```
$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

$ irb
> class Redis
> end
=> nil
> class Store
> end
=> nil
> defined?(::Redis::Store)
=> "constant"
> ::Redis::Store
  NameError (uninitialized constant Redis::Store
    Did you mean?  Store)
```
@grzuy
Copy link
Collaborator

grzuy commented Jan 30, 2018

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

@waruboy
Copy link
Author

waruboy commented Jan 31, 2018

Kinda amazing it goes up to ruby-lang bug

@grzuy
Copy link
Collaborator

grzuy commented Jan 31, 2018

Yup!

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

@grzuy grzuy added this to the 5.0.2 milestone Mar 8, 2018
@grzuy grzuy closed this as completed in #271 Mar 9, 2018
grzuy added a commit that referenced this issue Mar 9, 2018
[Fixes #253] Avoid 'defined?' buggy behavior in ruby 2.5.0
@grzuy
Copy link
Collaborator

grzuy commented Mar 10, 2018

Fix for this has been released in v5.1.0.

@waruboy
Copy link
Author

waruboy commented Mar 10, 2018

@grzuy thank you very much~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants