diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2010-03-12 16:00:01 +0000 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2010-03-12 16:00:01 +0000 |
commit | e68bfaf1fe1a7890a67af6f444281185f507cf9e (patch) | |
tree | 5e73caccdcdd65d0ac97f9eb92195928f30925f2 /actionpack/lib/action_dispatch/middleware/remote_ip.rb | |
parent | ef6462c73003b28c8e060a06120abb9cd67b6d52 (diff) | |
parent | 16846553b8866eab2aa3b128a2a23a221a25f7e3 (diff) | |
download | rails-e68bfaf1fe1a7890a67af6f444281185f507cf9e.tar.gz rails-e68bfaf1fe1a7890a67af6f444281185f507cf9e.tar.bz2 rails-e68bfaf1fe1a7890a67af6f444281185f507cf9e.zip |
Merge remote branch 'mainstream/master'
Conflicts:
activerecord/lib/active_record/base.rb
railties/lib/rails/configuration.rb
railties/lib/rails/log_subscriber.rb
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware/remote_ip.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/remote_ip.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb new file mode 100644 index 0000000000..c7d710b98e --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -0,0 +1,51 @@ +module ActionDispatch + class RemoteIp + class IpSpoofAttackError < StandardError ; end + + class RemoteIpGetter + def initialize(env, check_ip_spoofing, trusted_proxies) + @env = env + @check_ip_spoofing = check_ip_spoofing + @trusted_proxies = trusted_proxies + end + + def remote_addrs + @remote_addrs ||= begin + list = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : [] + list.reject { |addr| addr =~ @trusted_proxies } + end + end + + def to_s + return remote_addrs.first if remote_addrs.any? + + forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : [] + + if client_ip = @env['HTTP_CLIENT_IP'] + if @check_ip_spoofing && !forwarded_ips.include?(client_ip) + # We don't know which came from the proxy, and which from the user + raise IpSpoofAttackError, "IP spoofing attack?!" \ + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" + end + return client_ip + end + + return forwarded_ips.reject { |ip| ip =~ @trusted_proxies }.last || @env["REMOTE_ADDR"] + end + end + + def initialize(app, check_ip_spoofing = true, trusted_proxies = nil) + @app = app + @check_ip_spoofing = check_ip_spoofing + regex = '(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)' + regex << "|(#{trusted_proxies})" if trusted_proxies + @trusted_proxies = Regexp.new(regex, "i") + end + + def call(env) + env["action_dispatch.remote_ip"] = RemoteIpGetter.new(env, @check_ip_spoofing, @trusted_proxies) + @app.call(env) + end + end +end
\ No newline at end of file |