Receive POST from External Form - ruby-on-rails

I have a form on another website (using a different backend) that I want to be able to POST to my Rails application (on a different domain).
How do I generate a valid authenticity token for the external form so that my Rails app will accept it?
Assuming I can do the answer to the above question--is there anything else special I need to do to make this work? Apart from the authenticity token, the rest of it seems pretty straightforward to me...
Thanks for the help!

You can't generate an autenticity token from outside your Rails app.
What you can do, is to disable the token protection only for this action and use a custom implementation based on a before_filter.
skip_before_filter :verify_authenticity_token, :only => :my_action
before_filter :verify_custom_authenticity_token, :only => :my_action
def verify_custom_authenticity_token
# checks whether the request comes from a trusted source
end

You could just remove the check by adding a filter like:
skip_before_filter :verify_authenticity_token, :only => :action_name

Related

Ruby on Rails Telegram Notification. Is it secure?

I'm trying to use tele_notify gem:
Tele Notify
This Gem use Webhook, so I set it with Telegram:
https://api.telegram.org/bot<TOKEN>/setWebHook?url=https://<EXAMPLE.COM>/<TOKEN>
{"ok":true,"result":true,"description":"Webhook was set"}
Then in Application Controller:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
#IMPORTANT! THESE TWO LINES MUST COME AFTER protect_from_forgery!
skip_before_filter :verify_authenticity_token, :only => :webhook
include TeleNotify::Controller
#other code...
end
And finally the routes:
#config/routes.rb
Rails.application.routes.draw do
post '/<your token>' => 'application#webhook'
end
Is this code secure? Anyone experienced with this gem?
It is a problem to skip authenticity token?
skip_before_filter :verify_authenticity_token, :only => :webhook
Thank you very much!
Yes, it's quite secure. Intentionally or not, but you seem to be following official recommendations:
If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
As for skipping authenticity token check, it must be done, because telegram servers have no way of knowing the token. (it is precisely the idea behind the token and the check: remote servers, not knowing the token, can't make requests. But here you want them to be able to hit this certain endpoint).

Testing that Rails verify_authenticity_token is being skipped

I have an action in a Rails 3.2 application which skips verification of the authenticity token, as follows:
skip_before_filter :verify_authenticity_token, only: [:my_action_name]
However, from time to time, this gets removed accidentally by developers, and the app fails silently, losing the user's session on that particular (AJAX) action.
From within my functional tests, what is the simplest way to test that this before filter is being skipped for that action? I.e. what is the simplest way to test that this line has not been removed?
I would run:
before_filter :verify_authenticity_token, only: [:add, :your, :actions, :here]
and add only the actions you want to run verify_authenticity_token on

Get rid of X-CSRF-Token in Rails

I need to design a RESTful API for Rails, which will enable login from web browser, smart phone, tablet, etc. When I do login it always require X-CSRF-Token, so everytime I need to use session or cookie info. However the REST api should be stateless, which means shouldn't use cookies. Is there a way to get rid of that? Any suggestion for that?
Here's how I dealt with this in an app that responds with both HTML and JSON. I want the CSRF check except if it's an API call from a trusted source, so
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
# has to come after the protect_from_forgery line
skip_before_filter :verify_authenticity_token, :if => :api_request?
# but don't just accept any URL with a .json extension, you need something else to
# ensure your caller is trusted (in this case I test for a valid API key being passed)
before_filter :api_key_valid?, :if => :api_request?
def api_request?
request.format == 'application/json'
end
# ... etc
end

Rails / Devise Session Destroyed When Redirected From Paypal

Using Paypal payment standard. When the user is redirect the back to the app after paying on paypal.com, the logged in user becomes signed out. Any help is appreciated.
If you post to a rails app without providing the correct CSRF parameters, your session gets deleted. This sounds like what is happening. One way to solve this is to disable the CSRF meta protection for the paypal post action
In Rails3 you can disable the csrf token in your controller for particular methods:
In your controller:
1. protect_from_forgery :except => :create
or
2. skip_before_filter :verify_authenticity_token
or
to disable it for everything except a few methods:
3. skip_before_filter :verify_authenticity_token, :except => [:update, :create]

How do I secure this post request to Rails?

I'm trying to work out security for my AJAX calls. I've got a jQuery post call which deletes a note. From what I've read, it seems that I need to use protect_from_forgery to ensure that the post is coming from a valid user.
This is what I have so far
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
...
index.html
$.post('../delete_note',{id:$('#note_id').val()}, function(data) {
});
note_controller.rb
def delete_note
y params
render :text => "success"
end
At the moment, the post request gets run by Rails, even though I'm not sending any security token with it. What do I need to do secure the call?
I'm using Rails 3.0.1 and devise for user management.
You probably want to ensure the user is signed in, using in your note controller something like:
before_filter :authenticate_member!, :except => [:index]
Additionally, check if the user has the rights to delete the note, for that you want to use a authorization solution like cancan.

Resources