Returning supported HTTP methods with 'verify'

February 12th, 2007

When using Rails’ verify method to protect your ActionController actions, you should return a list of the allowed HTTP methods in the response headers.

Let’s say you have an action called update that you want to protect from anything but a POST. I like to do it like this:

:::ruby
verify :method => :post, 
  :only => :update, 
  :render => {:text => '405 HTTP POST required', :status => 405}, 
  :add_headers => {'Allow' => 'POST'} 

Now if someone tries to hit the update action with anything other than a POST, an error message will be displayed and the response headers will contain (among other things):

:::ruby
{"Status" => "405 Method Not Allowed", "Allow" => "POST"}

In my opinion, this is a better way to go than redirecting to another action because the use of an improper HTTP method is most likely the result of either programmer error or malicious intent. By redirecting to another page, you are making it much easier to for somebody to take your site down with a denial of service attack and if it’s a programming error, you’ll locate the problem faster.

You should also make sure that you have a functional test for this behavior:

:::ruby
def test_invalid_update_methods
  [:get, :put, :delete].each do |http_method|
    send http_method, :update
    assert_response 405
    assert_equal 'POST', @response.headers['Allow']
    assert_equal '405 HTTP POST required', @response.body
  end
end

Additional Resources