Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rack::Attack: Protect your app with this one we...

Rack::Attack: Protect your app with this one weird gem!

Mature apps face problems with abusive requests like misbehaving users, malicious hackers, and naive scrapers. Too often they drain developer productivity and happiness.

Rack::Attack is middleware to easily throttle abusive requests.

At Kickstarter, we built it to keep our site fast and reliable with little effort. Learn how Rack::Attack works through examples from kickstarter.com. Spend less time dealing with bad apples, and more time on the fun stuff.

Aaron Suggs

April 22, 2014
Tweet

More Decks by Aaron Suggs

Other Decks in Programming

Transcript

  1. # Example rack middleware class MyMiddleware def initialize(app) @app =

    app end ! def call(env) @app.call(env) end end
  2. # Example rack middleware class MyMiddleware def initialize(app) @app =

    app end ! def call(env) # Do stuff with the request @app.call(env) end end
  3. # Example rack middleware class MyMiddleware def initialize(app) @app =

    app end ! def call(env) # Do stuff with the request @app.call(env) # Do stuff with the response end end
  4. # In an initializer… # Throttle IPs to 10 reqs

    every 5 seconds module Rack::Attack throttle("ip", limit: 10, period: 5) {|req| req.ip } end
  5. # In an initializer… # Throttle IPs to 10 reqs

    every 5 seconds module Rack::Attack throttle("ip", limit: 10, period: 5) {|req| req.ip } end Rack::Request.new(env)
  6. # In an initializer… # Throttle IPs to 10 reqs

    every 5 seconds module Rack::Attack throttle("ip", limit: 10, period: 5) {|req| req.ip } end Discriminator
  7. # Making the cache key now = Time.now.to_i ! #

    Key changes each period key = "#{name}:#{now/period}:#{block_return}" ! # => "ip:279569154:127.0.0.1"
  8. # Throttle logins per IP throttle('logins/ip', limit: 5, period: 20)

    {|req| ! if req.path == '/login' && req.post? req.ip end ! }
  9. # Throttle logins per email throttle('logins/email', limit: 5, period: 20)

    {|req| ! if req.path == '/login' && req.post? req.params['email'].presence end ! }
  10. # Starve the trolls # <3 our community support team

    BANNED_IPS = Set.new ['1.2.3.4', '5.6.7.8'] ! blacklist('banned_ip') {|req| BANNED_IPS.include?(req.ip) && ! req.get? }
  11. Julian Doherty @ barelyknown Vipul A M Hakan Ensari Zach

    Millman @ alexchee Steve Hodgkiss T.J. Schuck Carsten Zimmermann Salimane Adjao Moustapha Jordan Moncharmont Pedro Nascimento Han Richard Schneeman Tieg Zaharia Navin Tristan Dunn Michael Jelks