Rails 3 - is link_to with parameters secure? - ruby-on-rails

As a general rule of thumb you aren't supposed to trust any input of data from users. If you had a simple link_to with a parameter:
link_to "Click me", test_path(:my_param => "test")
The route might look like: example.com/test?my_param=test
How do I know if the param, or any injected data for that matter, is being filtered properly? The Rails 3 API doesn't specify that it filters data that is passed to the controller, but I want to make sure that the params[:my_param] is filtered securely in the controller before I utilize the params data.
Any thoughts?

Rails framework doesn't secure things by default for GET request. link_to tag is sending a http get request.
If it is a POST/PUT/DELETE request then the Rails uses protect_from_forgery for verify the data sending url
However in your case, its not hard to write a simple method to verify your data for get requests ,
you could write a before_filter to check the sending parameters for a GET request
HTH

Related

Can I pass a param to the next routed URL?

If a url is localhost:3000/rooms/:token has a key in the params at this point named :token,
in the #show method in the controller I can ```params.merge!({ dev_paramater: 'hello'}) that would be present in the params when calling localhost:3000/rooms/:token, but when I go to localhost:3000/rooms/:token/chats the dev_parameter key disappears from params.
I would like to use data in the dev_parameter, I basically want it to persist if I visit deeper routes.
params is provided by the controller according to the request content when requests are received, they are independent in each requests. (BTW, params should not be modified in most cases.) If you need carry some information between requests, consider using session or cookies instead.
Rails guide:
session - https://guides.rubyonrails.org/action_controller_overview.html#session
cookies - https://guides.rubyonrails.org/action_controller_overview.html#cookies

Set params hash value using link_to without affecting url in Rails 4

When I submit a form, a number of parameters are set without showing up in the url.
I would like to do the same thing with link_to:
<%= link_to((purchase.paid ? 'yes' : 'no'), {action: :index, hidden_id: purchase.id}) %>
produces the url 'http://localhost:3000/purchases?hidden_id=1'. I would like to link to the url 'http://localhost:3000/purchases' while still setting params[:hidden_id] so I can access it in the controller, as if I had submitted a form.
My routes.rb file is as follows:
root to: 'products#index'
resources :products
resources :purchases
match ':controller/(:action/(:id))', controller: :shop, via: [:get,:post]
In answering this, is there anything I should know here about the difference in the way these two things are handled? Is it something about get vs post requests or is there some other principle involved which I'm not grasping?
Yes, it's to do with Get vs Post requests.
A Get request can only send parameters in the URL itself. A post request can also be sent to a URL that includes parameters in the URL itself, but it can also send parameters 'under the hood' so to speak.
So if your routes were set up to allow it, you could send either a get or a post request to http://localhost:3000/purchases?hidden_id=1, but only the post request could include additional parameters under the hood.
Anything else you should know about the difference in the way these two are handled? Yes. In most web frameworks, when you see the parameters server-side, they will be split up into GET params and POST params. Rails doesn't make this distinction, and puts them both in the same params hash. (I think this is silly, but whatever).
Also, a get request can be sent simply by entering the URL in your browser and hitting enter. A post request will generally only be executed by a user submitting a form on a web page. For this reason, get requests are not meant to change any content in your database. They should be for viewing information only. So, eg, if you have a button to delete a resource (eg. a blog post or something) it should be submitted via post. (more info on that at Why shouldn't data be modified on an HTTP GET request?)
Lastly, Rails provides an option in it's link_to helper to allow you to easily make the 'link' use a post request. See the method option at http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to. This basically uses javascript to prevent the normal action of clicking the link (which would be a get request), and submit a post request instead.

Preventing calls to my JSON api outside the html app

I've separated my front-end from my back-end, so that they communicate via JSON calls (generated by rails back-end).
i.e, my app calls get_info.json which runs a controller that returns ajax information to the front end.
How do I prevent a random user from directly running the get_info.json script, and thus directly accessing the JSON information?
You need to implement authentication for the json api.
It can be as simple as passing an api_key param to every request.
Or you can restrict the access to the route to a specific IP.
get "/posts" => "posts#show", :constraints => {:ip => '127.0.0.1'}
If front-end and back-end are in the same RoR application, then you can use CSRF token.
just pass a param to json call like get_info.json?token=<%= form_authenticity_token.html_safe %>, then in your back-end controller check if if params[:token] == form_authenticity_token.
hope this helps you.

Why doesn't direct path for delete/destroy exist in rails?

When you define a link_to in rails to delete an object/item you must specify method delete in that link_to, as compared to edit (edit_event_path(#event)) or show (event_path). Why is this the case?
In typical link_to links the browser will send HTTP GET requests. When you're destroying a resource the browser should send a HTTP DELETE request. Rails has some javascript that will run on those links and intercept the click to send a HTTP DELETE request for those marked with method: :delete. Also the path for a single resource to be destroyed and shown will be the same.
event_path will return "/event/1" or similar. When sending a HTTP GET request its expected that the show action of your controller will be called. When sending a HTTP DELETE request to the same path its expected that the destroy action will be called.
HTTP Verbs
Simply, Rails makes use of the HTTP Verbs which governs the web
Essentially, to keep routing structures simple, Rails allows you to generate a series of the "same" URL paths, each defined with different http verbs:
This means if you want to destroy an object, you can use the delete verb
--
OOP
A more specific definition for this lies with the object-orientated structure of Ruby (& Rails). The routing system is based around this structure (hence why they're called resources) - meaning if you treat the routing system as based around objects, you can begin to see a pattern emerge
If you're going to call a route for an object, IE to destroy that object, your route should be for the "object", not the "destroy" mechanism
In this sense, if you want to destroy an object, it makes much more sense to use the following:
<%= link_to "Destroy", object_path(object), method: :delete %>
This gives you the flexibility to create actions around objects, which can then be routed to the particular controller#actions as required

Get raw parameter data in Ruby on Rails

I have a ruby on rails api where I want to sign my request data by appending a hashed version of all passed in parameters to the request and rebuild this one at the server side as well to validate the integrity of the requests.
When I simply use the params method in the controller I have different parameters (e.g. for an update-method which is specified by this:
put 'login' => 'login#update'
I get as parameters on the server:
{"timestamp"=>"1399562324118", "secured"=>"xxx",
"login"=>{"timestamp"=>"1399562324118", "secured"=>"xxx"}}
although I only send the request from the client with
{"timestamp"=>"1399562324118", "secured"=>"xxx"}
Does any one have an idea how to get rid of this "login" parameter in the params list in a generic way? I do not want to exclude this for every single request of my api.
Thanks a lot!
Per the Rails Edge guide on ActionController:
"If you've turned on config.wrap_parameters in your initializer or calling wrap_parameters in your controller, you can safely omit the root element in the JSON parameter"
See http://guides.rubyonrails.org/action_controller_overview.html#json-parameters

Resources