A strange error in rails remote_ip middleware - ruby-on-rails

here is the error I found on rails production enviroment:
IP spoofing attack?!HTTP_CLIENT_IP="10.127.166.241"HTTP_X_FORWARDED_FOR="10.127.166.241, 61.164.36.180"
actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:55:in `calculate_ip'
So I digg into the rails remote_ip.rb sourcecode, go over calculate_ip, tested it locally, and found it should not happen, here is the test code:
forwarded_ips = "10.127.166.241, 61.164.36.180".strip.split(/[,\s]+/).reverse
client_ips ="10.127.166.241".strip.split(/[,\s]+/).reverse
!forwarded_ips.include?(client_ips.last) # return false?
According to my understanding after read the source code, caculate_ip sould return 61.164.36.180 instand of an error, anyone knows why? thanks~

Related

CableReady (Rails) Basic case giving mystifying error message

cable_ready 4.5.0
rails 6.1.4.1
ruby 3.0.2p107
This is a simple example from the basic tutorial (https://www.youtube.com/watch?v=F5hA79vKE_E) I suspect the error I am getting is because either cable_ready or rails evolved a little and created a tiny incompatibility.
I get this error in the JS console:
It is triggered when in my controller I ask cable ready to:
cable_ready["timeline"].console_log(message: "***** cable ready post created")
Which leads to my timeline_channel to:
received(data) {
console.log("******** Received data:", data.operations)
if (data.cableReady) CableReady.perform(data.operations)
}
My interpretation is perform causes this line in cable_ready.js line 13:
operations.forEach(function (operation) {
if (!!operation.batch) batches[operation.batch] = batches[operation.batch] ? ++batches[operation.batch] : 1;
});
Is finding something in the received data that it doesn't like.
That's where my trail ends. Can someone see what I am doing wrong, or tell me what other code you'd like me to include?
Solution: downgrade the version of the cable_ready javascript library.
I previously (maybe a year ago) did this tutorial using CableReady 4.5, Ruby 2.6.5 and Rails 6.0.4 and it worked like a charm back then as well as today.
But today, I tried this tutorial again on a duplicate project--same versions of CR, Ruby, and Rails and now I get java console errors similar to yours.
TypeError: undefined is not a function (near '...operations.forEach...')
perform -- cable_ready.js:13
received -- progress_bar_channel.js:8
I looked at the output of yarn list and saw that cable_ready was version 5.0.0-pre8 on the bad project and it was 5.0.0-pre1 on the good project. The downgrade could be accomplished with yarn add cable_ready#^5.0.0-pre1 in the bad project folder and now both projects work.
FYI for other newbies like me trying to understand how CableReady works: This tutorial gives another example of CableReady, and was also fixed the same way.

Rails 5: Error when removed quiet_assets_path from development.rb

I have been trying to upgrade my app from Rails 4 to Rails 5. In my Rails 4 version I have quiet_assets_path set but in Rails 5 it is not required. But when I removed that tried to start the server I am getting the following error,
> ruby-2.2.2/gems/rack-mini-profiler-0.10.2/lib/mini_profiler_rails/railtie.rb:93:in
> `>': comparison of Fixnum with nil failed (ArgumentError) from
> /Users/Admin/.rvm/gems/ruby-2.2.2/gems/rack-mini-profiler-0.10.2/lib/mini_profiler_rails/railtie.rb:93:in
> `block in <class:Railtie>'
Can someone help me with this?
Edit:
Following is my rack_profiler.rb,
if Rails.env.development? || Rails.env.production?
require 'rack-mini-profiler'
# initialization is skipped so trigger it
Rack::MiniProfilerRails.initialize!(Rails.application)
Rack::MiniProfiler.config.skip_schema_queries = true
Rack::MiniProfiler.config.skip_paths += %w(/admin/sidekiq)
Rails.application.middleware.delete(Rack::MiniProfiler)
Rails.application.middleware.insert_after(Rack::Deflater, Rack::MiniProfiler)
end
When I comment the delete line then server is starting but if the line uncommented then the server breaks.
thanks for the update. First of all, do you use Rack::Deflater middleware in development environment too?
I think this issue might help you. It basically says that in Rails all delete middleware operations are issued at the end. You can use the swap method as described in the above issue.
If you search the repo issues for "Deflater" you'll find a lot of results, but I believe the above contains your fix.

"undefined method `call' for #"

I have Rails 3 running on Apache 2 Server, and it sometimes without any reason it raise this error
"undefined method `call' for #"
and when restart Apache by
service httpd restart
it works
please, any idea why it raise this error ?
Thanks
My guess is you're looking at this in a web browser and the # is just the start of something like
#<User id: 1, username: ... >
Also worth nothing that stack overflow itself will mess that up unless its in code blocks. So it could be that you added more information that the SO rendering has "swallowed".
Anyway that will help you start, but you haven't begun to give enough information for anyone to help with the actual error.

Activesupport / Multi json: "Did not recognize your adapter specification"

I have a Ruby 1.9.3 / Rails 3.1 project with the following in the gemfile:
gem 'rails', '3.1.12'
gem 'json'
gem 'multi_json', '1.7.7'
That version of rails sets activesupport to 3.1.12 as well. I'm not sure what the exact cause of the problem is, but when running bundle exec rake test, I got the error:
/home/user/.gem/ruby/1.9.3/gems/multi_json-1.7.7/lib/multi_json.rb:121:in 'rescue in load_adapter': Did not recognize your adapter specification. (ArgumentError)
...
(more stack trace, including activesupport methods)
Fortunately I found a solution! See below.
Edit: My original answer is outdated and incorrect; read it if you please, but please read the updated information at the bottom.
After viewing a ton of other questions such as these ones:
OmniAuth Login With Twitter - "Did not recognize your adapter specification." Error
Capistrano deploy: "Did not recognize your adapter specification" during assets:precompile
https://github.com/intridea/multi_json/issues/132
I hadn't found a solution, so I dove into the library and determined that load_adapter was receiving the parameter "JSONGem". The alias was failing, and the method attempted to load
/home/user/.gem/ruby/1.9.3/gems/multi_json-1.7.7/lib/multi_json/adapters/JSONGem.rb
This file doesn't exist, but .../json_gem.rb does exist! So I modified load adapter as follows:
def load_adapter(new_adapter)
# puts "new_adapter: #{new_adapter}" # Debugging
# puts "new_adapater.class: #{new_adapter.class}" # Debugging
case new_adapter
when String, Symbol
new_adapter = ALIASES.fetch(new_adapter.to_s, new_adapter)
new_adapter = "json_gem" if new_adapter =~ /^jsongem$/i # I added this line
# puts "final adapter: #{new_adapter}" # debugging
require "multi_json/adapters/#{new_adapter}"
klass_name = new_adapter.to_s.split('_').map(&:capitalize) * ''
MultiJson::Adapters.const_get(klass_name)
when NilClass, FalseClass
load_adapter default_adapter
when Class, Module
new_adapter
else
raise NameError
end
rescue NameError, ::LoadError
raise ArgumentError, 'Did not recognize your adapter specification.'
end
This fixed the problem for me. It's probably not an optimal solution (ideally I would understand WHY the ALIASES.fetch failed, if that is indeed what happened, and fix that), but if your problem is similar then hopefully this quick fix can help.
Update
It's not viable for deployability reasons to modify someone else's gem. Fortunately I found the root cause of the problem. In project_root/config/initializers/security_patches.rb, we had the line
ActiveSupport::JSON.backend = "JSONGem"
This was the recommended fix to a security bug in older versions of rails. Now that we are on a newer version of rails (i.e, > 3.0), we can simply replace "JSONGem" with "json_gem" (which is what my original modification was doing, in a roundabout way) and not worry about the security issue.

How to handle exception generated from Rack before reaching your rails app

I have a jruby rails application running under tomcat. Some malformed query string in url cause Rack to choke with the exception stack trace being shown in production mode. Is there a way to handle that gracefully. I don't think I can use config.exception_app as that will only handle exception generated from the rails app. In this case, the exception is generated before it get to the rails app. Here is the exception:
org.jruby.exceptions.RaiseException: (ArgumentError) invalid %-encoding (/"{}\%#$())
at Module.decode_www_form_component(jar:file:/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/lib/gems-gems-jruby-jars-1.7.3-lib-jruby-stdlib-
1.7.3.jar!/META-INF/jruby.home/lib/ruby/1.9/uri/common.rb:898)
at Rack::Utils.unescape(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:41)
at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:94)
at org.jruby.RubyArray.map(org/jruby/RubyArray.java:2361)
at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:94)
at org.jruby.RubyArray.each(org/jruby/RubyArray.java:1613)
at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:93)
at Rack::Request.parse_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/request.rb:332)
at Rack::Request.POST(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/request.rb:209)
at Rack::MethodOverride.method_override(/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/gems/gems/rack-1.4.5/lib/rack/methodoverride.rb:26)
at Rack::MethodOverride.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/methodoverride.rb:14)
at Rack::Runtime.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/runtime.rb:17)
at ActiveSupport::Cache::Strategy::LocalCache::Middleware.call(/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/gems/gems/activesupport-
3.2.13/lib/active_support/cache/strategy/local_cache.rb:72)
at Rack::Lock.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/lock.rb:15)
at Rack::Cache::Context.forward(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:136)
at Rack::Cache::Context.pass(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:143)
at Rack::Cache::Context.invalidate(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:155)
at Rack::Cache::Context.call!(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:71)
at Rack::Cache::Context.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:51)
at Rails::Engine.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/railties-3.2.13/lib/rails/engine.rb:479)
at Rails::Application.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/railties-3.2.13/lib/rails/application.rb:223)
at Rack::Handler::Servlet.call(file:/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/lib/gems-gems-jruby-rack-1.1.13.1-lib-jruby-rack-
1.1.13.1.jar!/rack/handler/servlet.rb:22)
if the Ruby runtime is booted - which in this case seems it is ... you should be able to configure a (minimal) rack error application just set smt rack-y (require 'my_error_app'; run MyErrorApp) into the jruby.rack.error.app context parameter (e.g. in your web.xml with Warbler)
I ended up writing a rack middleware to handle the exception gracefully. I insert the middleware before MethodOverride middleware which is where it throws the exception.

Resources