8.6. Encryption and Secure Certificates
Ask a typical user what they know about security on the Web, and the first thingperhaps the only thinghe'll mention is Secure Sockets Layer (SSL), or more likely, "the padlock icon." Unfortunately, most people assume that SSL is a silver bullet that makes a site completely secure. But the reality is that none of the vulnerabilities we've looked at in this chapter are eliminated by SSL. Certain types of attacks are prevented by SSL, but far from all of them, so don't let the padlock icon lull you into a false sense of security.
SSL (and by extension, the https: URL scheme) provides two distinct functions: encryption and host authentication. Encryption essentially creates an opaque tunnel between the web browser and the web server. Anyone observing the traffic (such as any of the ISPs between the two endpoints, or someone sharing a Wi-Fi connection with the client) would know that something was being transferred between the two parties but have no way of seeing what. Of course, it's important to remember that once the web server decrypts the message, it's once again open to prying eyes.
So encryption creates an impenetrable tunnel. That's good, but not sufficient, because encryption doesn't ensure that the tunnel leads to the right place. That concern is addressed by the second function of SSL, host authentication. SSL certificates are tied to a specific domain, so if a middleman tries to impersonate the server, the certificate check will fail, alerting the user to an attack.
SSL is implemented by the web server, not Rails itself, so that's where the certificate should be configured. But Rails can detect whether a request used SSL and enforce whether or not secure requests are permitted.
For example, it's common for an e-commerce site to insist that billing information (such as credit card numbers) be submitted via SSL. But you might want other actions, like browsing the catalog, to require a nonencrypted connection because SSL creates unnecessary CPU overhead for those kinds of requests.
Another typical pattern is allowing (but not requiring) a secure connection for some users (but not all)if they've paid extra for a premium account, for instance.
Both of these situations are handled easily by the SSL Requirement plug-in. For example:
class ApplicationController < ActionController::Base include SslRequirement end class OrdersController < ApplicationController ssl_required :create ssl_allowed :show # ... end
To install, use script/plugin from the application root directory:
script/plugin install \ http://dev.rubyonrails.com/svn/rails/plugins/ssl_requirement
For full usage, see the README at vendor/plugins/ssl_requirement/README.
8.6.1. Ajax over SSL
Remember that the same-origin policy ensures that XMLHttpRequest objects will only create requests for URLs of the same origin as the main pagewhere origin is defined as the combination of domain, port, and protocol. Since unencrypted requests use the HTTP protocol and encrypted requests use the HTTPS protocol, they will always be different origins. In other words, a page loaded from http://example.com won't be allowed to send XMLHttpRequest requests to https://example.com and vice versa.
As a result, you can be assured that if the main page is loaded secured with SSL, any Ajax requests happening in the background will be, too.