3

My setup: Rails 3.0.9, Ruby 1.9.2

My app requires that only a certain part of my site be SSL protected and the rest not. In case anyone thinks this isn't normal behavior, check out Amazon. When merely browsing for products, it's in HTTP mode, during checkout, it switches to HTTPS. Even in the middle of a secure checkout transaction, there are several other links on the same page that are HTTP only.

I looked at ssl_requirement gem and decided not to use it because it isn't a complete solution for my needs. I ended up setting up specific SSL routes like

resources :projects do
    resources :tasks, :constraints => { :protocol => "https" }
end

In my view code, for HTTP specific links

<%= link_to 'Projects', project_url(@project, :protocol => "http") %>

and to handle HTTPS specific link

<%= link_to 'Task', new_project_task_url(@project, :protocol => "https") %>

I understand this isn't the cleanest way but it's what I have decided to do. The problem with this setup is how to properly set both HTTP and HTTPS links on every page. There is a proposed solution here but it requires wholesale changes _path to _url and I prefer to avoid that if at all possible. The solutions involves adding this method in

application_helper.rb

module ApplicationHelper
  def url_for(options = nil)
    if Hash === options
      options[:protocol] ||= 'http'
    end
    super(options)
  end
end

So my question is it possible to change this method or another one to change _path calls to explicit urls so I can use the above method to set the proper protocol.

Community
  • 1
  • 1
Bob
  • 8,424
  • 17
  • 72
  • 110

2 Answers2

2

you could try this, although I'm not 100% sure it works:

Use the proposed changes from the stackoverflow answer

Add this to application_controll.rb:

class ApplicationController < ActionController::Base
  def url_options
    { :host => request.host }.merge(super)
  end
end

According to the Docs it should add the full url even if you use _path:

:only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (true by default unless :host is specified).

sled
  • 14,525
  • 3
  • 42
  • 70
  • Thanks for the suggestion but this change applies to `url_for` which I am trying to avoid. I'm trying to find a way not to have to make wholesale changes from `_path` to `_url` or perhaps I misunderstood your intention. – Bob Jul 29 '11 at 19:12
  • my intention was that maybe the named _path function will call `url_for` in the background with the `:only_path` option set, but the `:only_path` option is ignored when a host is specified. – sled Jul 29 '11 at 20:09
  • Ah ok, now I get you. I wonder if `_path` does call `url_for` in the background, where would I even go to read the source code for `_path` helpers, do you know? Does anyone know? – Bob Jul 29 '11 at 20:46
  • I tried it and it didn't work as we hoped, any other thoughts? – Bob Jul 29 '11 at 20:56
0

My app requires that only a certain part of my site be SSL protected and the rest not.

That's your faulty assumption. The secure premise is that if some of your app requires SSL, then all of your app requires SSL. The correct assumption then is that your entire app requires SSL.

If your app requires SSL, then you should use something simple like rack-ssl which sets the HSTS header and enforces the secure flag on cookies in all responses.

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
  • I disagree, I think your assumption is faulty. It's standard behavior for popular e-commerce sites like Amazon to have a mix of HTTP and HTTPS links. When merely browsing for products, it's in HTTP mode, during checkout, it switches to HTTPS. Even in the middle of a secure checkout transaction, there are several other links on the same page that are HTTP only, so it's a mixture. – Bob Jul 29 '11 at 18:48
  • 1
    An attacker can MITM the product-browsing page, rewriting the original HTTPS links to the checkout to become HTTP links which the MITM intercepts and sends to the server as HTTPS. The best policy at present is always-SSL with HSTS: an attacker has to MITM the very first request to get around that. – yfeldblum Jul 29 '11 at 19:15
  • I didn't say that a MITM attack couldn't happen and there is no such thing as 100% security. Plus if this is such a huge issue, I am sure Amazon would have changed their entire site to use HTTPS given the volume of transactions going through their site. Look, I appreciate your feedback but let's just agree to disagree. – Bob Jul 29 '11 at 19:24