0

I am currently working on an avatar app powered by Rails where users can upload avatars for their user profile.

I would like to use a custom HTTP header to block public upload requests and only allow requests from my apps. How would I go about doing this with Ruby on Rails?

I am uploading the avatars using AJAX so this may be a bit harder. Also I would prefer not to show the header in the public HTML code otherwise it defeats the object of adding it!

2 Answers2

0

If you add

 protect_from_forgery

to your application controller, it will block all NON Get requests from 3rd party links. It will add a hidden input value to each form with an authentication token that will be used to check all data that is sent to the servers.

Further reading

http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

Rails 3.1 - CSRF ignored?

Community
  • 1
  • 1
Kyle C
  • 4,077
  • 2
  • 31
  • 34
  • I'll be using POST requests because the user will be uploading an avatar so I don't think this helps :/ –  Jul 30 '12 at 22:21
  • It will not block POST requests made from users on your own site, it will work fine. It will just block POST requests made from 3rd party sites. – Kyle C Jul 30 '12 at 22:37
  • Hmm ok, but this avatar app will be remote, it will be on a different domain. E.g. my new avatar Rails engine app mapped at app123.com/avatars which sends a post with the users uploaded avatar to myapp.com –  Jul 30 '12 at 22:46
  • You can always add the csrf token to your ajax request, check the last link I posted. As long as the request has the correct authentication token it will be accepted – Kyle C Jul 30 '12 at 22:48
  • Ah ok, I will take a look into it, thanks. But could a hacker possibly copy that CSRF token and use it, pretending to be my app or not? –  Jul 30 '12 at 22:49
  • The CSRF is a digital signature and can always be ready by the user/hacker (just check your page source). It is uniquely generated ( calculated from the current session and the server-side secret), you shouldnt have a security issue – Kyle C Jul 30 '12 at 22:56
0

You could implement a custom HTTP header (say X-Foobar-Validity-Status: valid) and check it in a before_filter.

class YourController < ApplicationController
  before_filter :check_header

  def check_header
    unless request.headers['X-Foobar-Validity-Status'] == "valid"
      render json: {"error" => "You are an evil attacker. Go away"}
    end
  end
end

However, I would consider this a bad idea.

  • Attackers can read the packet dump of your HTTP requests and add the headers, even with jQuery. See the jQuery.ajax headers option.
  • Instead of using a proprietary header, I would use User-Agent for this purpose.

Instead, I would sugest using the protect_from_forgery mechanism of rails. It makes your life easier and is more secure. Just fetch the authenticy token by a http request in your app and then send it back with your request. This should keep intruders out.

iblue
  • 29,609
  • 19
  • 89
  • 128
  • I can set and check HTTP Headers, that's not the problem. I was just looking to see if it was possible to add a HTTP header (X-My-App) to the form_for tag or can I post it locally, add the HTTP header and then send the request to my avatar server? –  Jul 30 '12 at 22:22