Thursday, February 14, 2008

A Couple of Tiny Rails SSL Helpers

Here are a couple of helper methods for ensuring forms are set to submit via https in the production environment (but not in dev), and for redirecting back out of SSL afterward. Since SSL can be resource intensive on the server, it's usually good to hop back out into cleartext unless the nature of the application (e.g., financials) warrants encrypting the whole session.

To create a form that uses, SSL, just replace form_tag with form_tag_using_SSL_in_production.

In application_helper.rb:

def production?
ENV["RAILS_ENV"]=='production'
end

def form_tag_using_SSL_in_production form_args, &block
form_args[:protocol], form_args[:only_path] = 'https', false if production?
form_tag form_args, &block
end

form_for is the preferred helper ... if it's actually a "form for" a model object, which this one was not. I'll leave the analogous form_for_using_SSL... as an exercise for the reader.

When you're done with the relevant action processing, any content rendered is going to get sent back under the SSL connection. At some point (in my case, immediately) you want to redirect out of SSL. Just use redirect_and_drop_SSL the same way you would use redirect_to.
In application.rb:

def redirect_and_drop_SSL destination
destination[:protocol], destination[:only_path] = 'http', false if request.ssl?
redirect_to(destination)
end

You might be thinking this stuff is too trivial to post about, and anyone who needs to use SSL knows this stuff already. Unfortunately, that's not entirely the case, as I'll write about in my next post.

8 comments:

Brian Getting said...

I have been trying to figure out the "trivial" task of creating a helper that will wrap "form_for" and make it force SSL.

Admittedly, I am having some troubles, would you mind placing some sample code up? Also, how does this method interact with the ssl_requirement plugin.

Adam said...

@bgetting: ssl_requirement is actually a nice high-level solution for requiring SSL or switching out at the "page" level (e.g. you make your whole login page require SSL, not the login form)

the problem is that if you have a form that submits via HTTP, it's gonna submit in the clear, then hit ssl_requirement on the server -- but by then the credentials or whatever have already been sent in the clear.

an example of where this is a problem is your standard site with a login box on the homepage -- for load reasons you don't want to require all visitors to view the homepage over SSL, but otherwise you need to make sure the login form submits via HTTPS the first time it talks to the server...

as for a form_for wrapper, here's a quick SWAG at a general one:

def
  form_for_using_SSL_in_prod(record_or_name_or_array, *args, &proc)
  options = args.extract_options!
  options [:protocol], options [:only_path] = 'https', false if production?
  form_for record_or_name_or_array, *args, &proc
end

this should hopefully be more general than the form_tag version I posted, which works for my app but doesn't actually allow for the full expressiveness of the form_tag arg options

Anonymous said...

Thanks for posting this. ssl_requirement is deceptively easy to use, but as you said in the comments, it only gets you halfway.

Luckily, I have a partner who is more security aware than me and he caught this mistake in our code before we launched it.

Jack said...
This comment has been removed by the author.
Jack said...
This comment has been removed by the author.
Unknown said...

I had to modify the form_for helper to get it to work- I think the example modifies the :url hash but doesn't add it back to the arguments. This worked for me:

def form_for_using_SSL_in_prod(record_or_name_or_array, *args, &proc)
options = args.extract_options!
options[:url][:protocol], options[:url][:only_path] = 'https', false if production?
args << options
form_for record_or_name_or_array, *args, &proc
end

Buy WOW Gold said...

Again great publish. You seem to have a very good knowledge of these kind of themes or templates.After i getting into your website,I thought this specific . Seriously and make blogging your website is often more attractive. For your Success!

Buy RS Gold
Buy Cheap RS Gold

Taylor Bara said...

Do you want to improve your writing skill? Then you should have a peek here for the best tips and examples!