Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

136 | Chapter 5: Security


This is not to say that you should publish your routes and system architecture; there
is no need to aid an attacker.Defense in depth(having multiple redundant layers of
security) is an important principle as well. But the guiding principle is never to rely
on secrecy for security.


Secure Your Error Messages


Error messages can reveal a lot about the configuration of your servers. Even the default
Apache error messages may reveal semi-sensitive information through the server sig-
nature line:


Apache/1.3.36 Server at http://www.example.com Port 80

You don’t necessarily want to volunteer this information to a potential attacker. In
addition, the HTTPServerheader often contains more detailed information, includ-
ing a list of all server modules that are installed and their versions. You can reduce
this information to a minimum with two lines of Apache configuration. Put these at
the top level of the Apache configuration file:


ServerSignature Off
ServerTokens Prod

In Rails, you can also inadvertently expose stack traces and source code on error if
you don’t ensure that Rails knows which requests are “local.” By default, in develop-
ment mode, the ActionController::Base.consider_all_requests_local configura-
tion attribute is set totrue. This means that every uncaught exception will show a
stack trace (with source code), regardless of the source I Paddress. This is fine for
local development, but it is insecure if you have a development server open to the
public Internet. Theconsider_all_requests_localdirective is disabled by default in
production mode.


You can override the defaultlocal_request?function in yourApplicationController
if you have more complicated rules regarding what constitutes a local request (such
as addresses on the public Internet from which you develop):


class ApplicationController
LOCAL_ADDRS = %w(123.45.67.89 98.76.54.32)
def local_request?
LOCAL_ADDRS.include? request.remote_ip
end
end

In any case, try triggering some exceptions on your public servers with a temporary
action like this one:


class UserController < ApplicationController
def blam
raise "If you can read this, your server is misconfigured!"
end
end
Free download pdf