RE: [coldbox:13237] SSL Interceptor

What I assume is happening is that buildLink() defaults to making HTTP links. “View Source” in one of your pages and you will see that all the links point to HTTP. I assume you have something at the web server level which is disallowing HTTP. This will essentially defeat the purpose of the SSL interceptor whose job is to catch HTTP requests and redirect them (with cflocation) back to the same URL, but on HTTPS. If your web server won’t allow HTTP to begin with, the SSL interceptor will never kick in.

event.buildLink() doesn’t know about or care about your SSL interceptor, nor does it pay any attention to it when it creates your links. If you want your links to be built secure in the first place, you must use the SSL=true parameter. I abstracted my list of secure events out into a model object called SSLService and modifed the SSL interceptor to consult with the SSLService. I also created a buildLink() in my requesetContextDecorator which consults the SSLService() when building a link.

I your case, you ALWAYS want secure (unless you’re using build link to create links somewhere other than your site) so I would recommend adding a request context decorator (http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbRequestContextDecoratorGuide) and pass SSL=true along to all your buildLink() calls.

Now, there is one last item which is not as easily fixed (though it may be possible with some of the new WireBox AOP stuff…) and that is your setNextEvent() calls. If you do stuff like this inside your handler to redirect to another event:

setNextEvent( event=‘handler.action’);

it is basically a cflocation and it defaults to HTTP unless you pass in the SSL=true. There’s no way to globally change or override that without modifying the core of coldbox. I have added the following in every single setNextEvent in my app:

setNextEvent( event=‘handler.action’,
ssl=SSLService.isSSLRequired(rc.xehNSEventExpired ));

You could probably just do an extended find and add SSL=true into all of them.

Of course, if you are manually making any urls, you will need to specifiy HTTPS for them as well. At that point every URL that makes it back to your browser will all be HTTPS and your SSL interceptor won’t really be needed.

Of course, you can ignore everything I said above if you want to simply allow HTTP requests through your web server (which I assume you are blocking) and then just let the SSL interceptor do its job and bounce the browser back. I don’t like this for two reasons though:

  1. twice as many trips to the server to bounce every request back to secure
  2. All request data (URL, FORM, Cookie, etc) is sent un-encrypted for the first request prior to being bounced back as secure.

Let me know if that all makes sense.

Thanks!

~Brad

Thank you for the awesome information Brad. I agree with you, I am not a big fan of the forcing ssl through apache. 1 thing I found that caused some issues was cfformprotect. No matter what I did because of the quick redirect it kept thinking that the form submission was spam. So it looks like what I need to do is setup a self signed cert on my local machine so my dev environment is secure and then change all of the links to ssl = true and go from there. Thanks for the help Brad!

What I did in one of my apps was this :-

  • Not use the SSL interceptor at all…
  • Use Apache to force all HTTP to HTTPS (like you have already)
  • Change the event.sesBaseURL (which event.buildLink uses internally) using an Interceptor (see how it uses https if event.isSSL() is true)

interceptors = [
{
class=“interceptors.MultiDomainSeS”,
properties={}
},
{
class=“coldbox.system.interceptors.SES”,
properties={LooseMatching=false}
},

Code for MultiDomainSes.cfc

if(arguments.event.isSSL()) { arguments.event.setSESBaseURL("https://" & cgi.http_host); } else { arguments.event.setSESBaseURL("http://" & cgi.http_host); }

And in the Layout file - add this in the HEAD section