Post form data to Rails backend from outside app - ruby-on-rails

For marketing reasons we want to a/b test some landing pages. Fairly typical but, ideally, we'd like the page to post directly into our Rails backend (creating a new user). We plan to host our landing pages on Unbounce (or whatever, doesn't really matter) but it's not clear how to post to (users#create) in Rails app from a 3rd party form without running into CSRF and other security token issues.
Perhaps there is a better (read: best practice) for how to a/b test landing pages related to a Rails application? I'm trying to minimize changes to the codebase, if possible, required to run these landing page experiments.
Any thoughts greatly appreciated.

It's good that you're using the Rails defaults for security; you're letting the framework do good work for you! However, for what you're describing, the Rails CSRF protection defaults are going to get in the way. CSRF protection exists to protect signed-in users from having their account hijacked. Since this is your signup page, there is no signed-in user, so there's really nothing to hijack.
I recommend you do two things:
Skip the authenticity token check for this controller action only (example: skip_before_action :verify_authenticity_token, on: :create).
Don't accept the signup request if there's already a signed-in user.

Related

rails - What is the biggest security risk in intentionally disabling a CSRF check on the 'create' action?

I have a fully working product on Rails 5. I now wish to make a Chrome extension, using which users can create an 'Article'.
However, requests from my Chrome extension will be treated as Cross Site by my rails app. Hence, I was thinking of not doing the CSRF check at all on just my create action.
What is the biggest security risk associated with this? I understand after this, anyone will be able to make POST request to my server that creates a new article - however, this is not a damaging action like update, or worse, delete.
The Rails guide states that,
CSRF attack method works by including malicious code or a link in a
page that accesses a web application that the user is believed to have
authenticated. If the session for that web application has not timed
out, an attacker may execute unauthorized commands.
If a CSRF token is a valid one, it is a kind of assurance that the user session has not been hijacked and the request has been made with the user consent.
For more info, I recommend you to refer the Rails guide http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

session management in rails without User model

I have an rails app which relies on authenticating username/password entered to an external webservice. Rails app will not have a user model. When a user enters login/password and it makes a post request to check that login/password. External application will return back a cookie or token which can be used for subsequent requests made from rails app.
There is no User model in the rails app since all the users are stored in an external application.
Is there a gem which let me strictly do session management? I'm planning on storing that token in a session.
why not just create a sessions controller that saves the token into a session? I don't see a need for a gem.
something like
sessions[:token] = token
If you are dealing with a tokens that expire like facebook you can take a look at this
http://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens/
hope it helps
I might look at the way Michael Hartl does user sessions in his Rails tutorial. What you want is something slightly different, but you might be able to reuse some of what he did there. http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec-current_user
(It's also just a good tutorial to go through, regardless of your level of Rails experience.)

Security in angular.js with Ruby on Rails

What is the best way to make authentication?
on frontend I use Angular.js
on backend: Ruby on Rails
Rails app using as API for my frontend.
UPDATE:
This is will be single page application.
Frontend wiil be developed in Angular.js, backend in Ruby on Rails.
In ideal I want to build backend as collection of resources returned in json.
I search best method of security implementation.
When user open the app I need to check if user authenticated.
If not - go to login page,
If authenticated - open that he wants and return needed resource from backend.
I think that I need to store auth token on the client side.
What is the best method to generate it, or maybe Rails already generate it for me?
I don't know Angular.JS at all but I will try to provide you general information on rails that you can use with any Javascript Framework.
For authentication, you just needs:
A model for users
a controller which handle login, this method check user login/password, create a session object with all information needed (session is stored on server side and a cookie is used on client-side to associate each request to a session)
A controller for handling logout which basically only destroy the user's session
You have a good implementation in the rails tutorial here, or you can find several plugins (authlogic seems to be the recommendation of stackoverflow usershere).
Then, there is few differences between handling authentication with static html pages or with AJAX:
A HTML request will send login and password to the controller, which will automatically redirect it to another internal page once the session create
In AJAX, the javascript on client side should send an ajax request, look for the answer by the server (success / failure) and launch adapted actions (message if failure, redirection if success)
In both cases, the important thing is to check that the user is authenticated at at each controller otherwise anybody would be allowed to launch action or access internal information.
I'm trying to do something similar and I found this example app which has been very useful to get me going in the right direction: https://github.com/karlfreeman/angular-devise
Also checkout further discussion about it here: https://github.com/karlfreeman/angular-devise/issues/1
And here's another repo which takes a slightly different approach: https://github.com/colindensem/demo-rails-angularjs
I ended up borrowing ideas from all of the above. Here's a working demo if anyone's interested: https://github.com/jesalg/RADD

understanding where rails authenticity_token is necessary (static page login?)

I have been trying to work out if I can have a login form on my static homepage. I would like to have some static pages and it would be great to have a login form on them. I spent some time getting more familiar with the authenticity_token that is generated with form_tag and although I realize we want to generally check all requests that aren't GET requests I feel like it might be possible to leave it out for a login because we aren't trusting the user with anything until after they are logged in. If a malicious site tried to use CSRF at this point it would need to know the login and password at which point the user is compromised anyway.
I definitely don't want to open up any security holes in my application and I appreciate all that rails does to keep this working, but in this situation am I right to think I can just submit a form without the token?
The purpose of the token is so that data cannot easily enter your system unless it is coming directly from that form. When a user visits the site, they get a cookie that matches the token in the form. When the form is submitted, those tokens must match.
If someone can submit the data from outside the form, you are opening up the potential for a script to make continuous login attempts. It's fairly easy to write something that would automate going to your site, getting a cookie and logging in using the form, but it's definitely more work. Think of it as another layer of security that you can have without negatively affecting your users.

Rails authorization necessary for post actions?

I have an app I'm writing in rails 3 w/ cancan and devise. I'm curious if authorizing post actions on your controllers is necessary or helpful from a security standpoint? Assuming all my controller actions require authentication w/ devise (ie user must be logged in).
I can see why I need authorization through cancan on my controller actions that use GET's since a user can simply input the url they wish to visit freely and this must be locked down. However, with posts the user must post the data from a form, which is protected against an xss attack with a token.
In this case would it be safe to assume that if i limit the visibility of, say, a button in my view with cancan that the user wouldn't be able to submit a form maliciously?
Thanks alot
EDIT:
Thanks for the quick answer guys. As it has been pointed out below a malicious user can forge a form post using tools such as firebug and thus authorization is necessary.
What would be the best way to simulate this type of interaction (a user posting to an url with a form they've hacked) using capybara / cucumber?
Thanks again.
A user can submit a POST request regardless of whether they are on your website or not. You're correct in thinking that the security token will help prevent XSS, but I would add authentication in for other methods of attacks.
A good (free) ebook to read if you're concerned about security is the Ruby on Rails Security Guide. It outlines all common forms of malicious attacks and even explores some of the lesser used (but just as effective) methods. It also gives great solutions on how to make your application more secure.
You should validate a users authorization in the controller.
With simple tools like FireBug, you can edit the content of a form manually and even add more text fields or similar. The XSS protection won't help you with that.
The user would still be able to generate the button (any method from using Firebug to changing browser code would do) on client side and send the form. If I remember correctly tokens are sent in HTML header co it wouldn't be a problem to forge the form.

Resources