Which RESTful action should I use to redirect to another site? - ruby-on-rails

I have an app where I try to adhere to REST.
The app receives requests for external links that don't belong to the app, so the sole purpose of the action is to redirect the request to the external URL.
My suggestion is to have the following controller/action: redirects_controller#create.
Is my thinking correct or should it be the show action instead?

REST (apart from Rails) is about using the correct HTTP method for the correct action. The Rails part is just using the conventional controller action for a given HTTP method.
So, if you're doing a 301 or 302 redirect to another page, which browsers handle by issuing a GET request to the URL in the redirect response's Location header, do it in a show action. This will allow the user's browser to cache the other page when appropriate, and to not notify the user before redirecting.
(There is a way to redirect POSTs, but you didn't mention it so I expect you're talking about regular 301/302 redirects.)

Coming from a Java background, the REST actions must be related to CRUD operations. Requests that do not change the resource like in your case where the intent is to redirect to another page must be tied to a GET verb or show in your example.
If you were to create a new resource you would use POST.
A more detailed explanation can be found in Richardson's rest maturity model level 2

Related

How to handle unauthorized accesses gracefully in backend?

I have a Ruby on Rails application which redirects users to the start or login page if they end up at a resource they are not authorized for.
For that, it redirects through a 302 Found.
This does not feel right to me, as for example a successful creation of a resource via POST also returns a 302, with the only difference being that it redirects to the created resource.
On the other hand, it does not seem possible to redirect a user without returning a 30X status code (401/403 in this case).
Am I missing something here, or am I already doing it correctly and this is just the way to go?
Well I'd say that it depends of the context, for an API I'd go for you way, if the user is trying to reach an endpoint without authentication or without enough permissions, I'd return a 401 or 403 respectively.
But for a web application without a separated frontend app, you've no choice to tell to the browser where it has to go next and the only way of doing this is to use redirections (that are only 3xx HTTP codes => https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages).

Does RedirectToAction pose a security risk?

I have an HTTPS post coming in via a secure form. Without going into lengthy explanation: I need to call an action within the same controller that accepts two tokens passed as parameters. When I run Fiddler, I see that that method is being called with the parameters in the URL. My question is: Does this pose a security risk? Is there a more secure way of redirecting within the same controller?
Yes, it poses a security risk, but it is easily mitigated by simply validating that the urls you are redirecting to are within the same domain as your source destination.
In fact, this is on the OWASP top 10.
A10 - Unvalidated Redirects and Forwards
EDIT:
I just realized that I missed the "ToAction" part of the question, so no.. It's not really possible to redirect outside of the site with RedirectToAction, so there isn't a worry for that. However, if you are using direct user input to feed into your RedirectToAction (and that includes accepting post data that you generate in a different page) then it's possible that an attacker could redirect to a method you did not anticipate. However, this is no different from a user simply trying random URL's and hitting one, or knowing a url and going to it manually. You need to have authorization in place to prevent access to URL's that the user does not have authorization to view.
If the original Action is accessed via HTTPS then RedirectToAction will redirect to a relative URL on the same domain using the same protocol.
So if your original page is
https://www.example.com/Foo/Bar
and this redirects to the FooBar action with some route parameters:
https://www.example.com/Foo/FooBar/1/2/3
an attacker cannot read the parameters 1/2/3 nor the rest of the URL.
However, the things you should bear in mind are:
The URL parameters will be logged by default by the browser (history), your server, by corporate proxy servers and possibly by other devices on your network by default.
If the user follows any links from your page to other https URLs, the referer HTTP header will contain your page address including parameters. Modern browsers will not send the referer header with http links though.
If there are any other https resources on your page this will cause the browser to send the referer header with the request.
For these reasons, if your parameters (1/2/3) are private, then you may wish to POST this data to the target page rather than use RedirectToAction (which results in a GET).
Note that you should be validating that the current user has access to the resources that 1/2/3 refers to (e.g. if the parameters were an order ID, you should check that the user identified by their auth cookies allow them to see the order referenced). Keeping 1/2/3 private are only beneficial if the parameters are themselves sensitive (e.g. a social security number).
Note that the OWASP Top 10 vulnerability, "A10 - Unvalidated Redirects and Forwards" does not apply here as RedirectToAction can only redirect to another action. If the other action redirects to a user set URL, then the vulnerability would lie there instead.

Redirect() vs RedirectPermanent() in ASP.NET MVC

Whats difference between Redirect() and RedirectPermanent(). I had read some articles, but I don't understand when we must use Redirect() and RedirectPermanent(). Can you show a pieces of example.
The basic difference between the two is that RedirectPermanent sends the browser an HTTP 301 (Moved Permanently) status code whereas Redirect will send an HTTP 302 status code.
Use RedirectPermanent if the resource has been moved permanently and will no longer be accessible in its previous location. Most browsers will cache this response and perform the redirect automatically without requesting the original resource again.
Use Redirect if the resource may be available in the same location (URL) in the future.
Example
Let's say that you have users in your system. You also have an option to delete existing users. Your website has a resource /user/{userid} that displays the details of a given user. If the user has been deleted, you must redirect to the /user/does-not-exist page. In this case:
If the user will never be restored again, you should use RedirectPermanent so the browser can go directly to /user/does-not-exist in subsequent requests even if the URL points to /user/{userid}.
If the user may be restored in the future, you should use a regular Redirect.
RedirectPermanent is 301 and Redirect is 302 status code
They send different response codes to the browser. 301 is a permanent redirect, 302 a temp one. The end effect is the same, but if the client wants to index links (the most common client that does this will be search engines) then a permanent redirect tells the client to update its records to ignore the old link and start using the new one. A temp redirect tells the client that the page is redirecting for now, but not to delete the old link from its indexing database

ruby rails web request response lifecycle

I'm a novice in ruby on rails trying to understand the in-depth flow of a typical request/response life cycle in ruby on rails web application.
I have googled for the info and have not found an answer which is complete or detailed to the level of DNS servers to dispatchers.
The closest I got to a good explanation is at:
http://brainspl.at/request_response.pdf.
Can someone point me to a better or more detailed explanation?
-Raviteja
So you are asking for rails request/response cycle and you already referred to a presentation which really describes it very well. So im assuming that you want to know it from a very high level and you need this concept totally for development. Then here it is. Im just trying to name the parts sequentially.
Route: Here you will draw the paths which will be used by the world to access your application. With a complete RESTful architecture, you need to define the hierarchy of your resources and define how a resource can be accessed to perform some action. If any request to your application doesnt match with any path in the routes file, it will not be processed. If any match occurs, it will find the corresponding controller and action and will call it. At the time of calling, it will store all the request related data in params hash.
Before Filters: Now your application already know which controller#method is gonna process the request. And it will check if there is anything configured to execute before calling that method. This is done by using before_filter. If found anything then those functions will be called first.
Method Execution: After executing all the before_filter methods in a particular sequence, it will call the actual method. All the data is available in params hash in this method. It processes input data, invokes Model calls for database access, and prepare data for view.
View: Proper view file will be chosen based on the controller#action, format. Or you might select any particular view to render by render :partial call. And the response will be prepared using the variables prepared in controller. This response will go to the client.
After Filters: After processing the view, it will look after_filter methods and will those if found.
Well this was a quick overview i would say, without really any details. Im saying again, the pdf you referred really contains more details.
Let me know if you want to know anything more specifically.
A user opens his browser, types in a URL, and presses Enter. When a user presses Enter, the browser makes a request for that URL.
The request hits the Rails router (config/routes.rb).
The router maps the URL to the correct controller and action to handle the request.
The action receives the request, and asks the model to fetch data from the database.
The model returns a list of data to the controller action.
The controller action passes the data on to the view.
The view renders the page as HTML.
The controller sends the HTML back to the browser. The page loads and the user sees it.
https://www.codecademy.com/articles/request-response-cycle-dynamic
and https://www.codecademy.com/articles/request-response-cycle-forms
Everything starts when ‘url’ requested by a user. The browser needs to know sever’s IP address to connect, So it lookup DNS(Domain name system) which translate your domain into the public IP address of the particular server. Then the Browser will do threeway handshake to connect server like puma in port 80. And decide upon public and private key it happen only because if url use HTTPS. HTTPS is a secure wrapper around HTTP and TCP. Then Server triggers the rails application through middleware like rack and provides request verb, header, body to the application. Then rails application use Journey (Default route library of rails) to find the consent controller and action which matches the request and call with the request and params.
Then rails lifecycle callbacks like before, after, around will be triggered during the process. The action takes care of requesting data from the model and rendering the consent view for the request. Finally sent back the status, header, and body as the response.
If you want to learn in-depth about lifecycle, check this article The Lifecycle of a Request
It is also important to note that Rails apps use an MVC architectural pattern, which is Model, View, and Controller at a high-level the life-cycle of a request in rails app is simply the interaction of the Model, View, and Controller. This article gives you an overview.

Redirecting a GET request to another app's POST request in a rails controller

I have a controller action that is triggered by a GET route, which under some conditions, I want to redirect to the POST route of another app on another server.
I'm aware of redirect_to "http://somewhere.com/thing_to_post_to" but there doesn't seem to be a way of specifying the http method. This intended for AJAX requests not pages, so it isn't acceptable to return a javascript to direct the browser.
Is this possible?
redirect_to uses HTTP status code to make the redirection, so it would likely be a GET, here's antoher explanation to use 307 status code
Response.Redirect with POST instead of Get?
but is not very well implemented among all browsers, so i suggest using a session variable to pass parameters among the views or something similar.

Resources