Is it safe to accept URL parameters for populating

2019-07-18 10:54发布

问题:

I am using Ruby on Rails 4.1.1 and I am thinking to accept parameters (through URL query strings) that are passed directly to the url_for method, this way:

# URL in the browser
http://www.myapp.com?redirect_to[controller]=users&redirect_to[action]=show&redirect_to[id]=1

# Controller
...
redirect_to url_for(params[:redirect_to].merge(:only_path => true))

Adopting the above approach users can be redirected after performing an action. However, I think people can enter arbitraryparams that can lead to security issues...

Is it safe to accept URL parameters for populating the url_for method? What are pitfalls? What can happen in the worst case?


By logging params during requests to my application I noted Rails adds always :controller and action parameters. Maybe that confirms url_for can be used the above way since it is protected internally and works as-like Rails is intended to.

回答1:

This it is safe internally as Ruby On Rails will only be issuing a HTTP redirect response.

As you are using only_path this will protect you from an Open redirect vulnerability. This is where an email is sent by an attacker containing a link in the following format (say your site is example.com).

https://example.com?foo=bar&bar=foo&redirect=http://evil.com

As the user checks the URL and sees it is on the example.com domain they beleive it is safe so click the link. However, if there's an open redirect then the user ends up on evil.com which could ask for their example.com password without the user noticing.

Redirecting to a relative path only on your site fixes any vulnerability.

In your case you are giving users control of your controller, action and parameters. As long as your GET methods are safe (i.e. no side-effects), an attacker could not use this by creating a crafted link that the user opens.

In summary, from the information provided I don't see any risk from phishing URLs to your application.



回答2:

Rails redirect_to sets the HTTP status code to 302 Found which tells the browser to GET the new path as you defined it by url_for. GET is a considered a safe method in contrast to

... methods such as POST, PUT, DELETE and PATCH [which] are intended for actions that may cause side effects either on the server, or external side effects ...

The only problem would have been if someone could gain access to methods such as create and destroy. Since these methods use HTTP methods other than GET (respectively POST and DELETE) it should be no problem.

Another danger here is if you go beyond CRUD methods of REST and have a custom method which responses to GET and changes the database state:

routes.rb

resources something do
  member do
    get :my_action
  end
end

SomethingController

def my_action
  # delte some records
end

For future ref:

Rails has a number of security measurements which may also interest you.



回答3:

It's not exactly an answer, just wanted to point out that you shouldn't use something like

url_for(params)

because one could pass host and port as params and thus the url could lead to another site and it can get worse if it gets cached or something.

Don't know if it threatens anything, but hey, it's worth pointing out