Disclosing system information helps an adversary learn about your site and form a plan of attack. Try to reveal as little about your technology stack and architecture as possible, beyond what is essential for your users to know.
Risks
Revealing system information makes life easier for an attacker, and gives them a playbook of vulnerabilities they can probe for. It may not be feasible to completely obscure your technology stack, but some simple steps can go 90% of the way to discouraging most attackers. Be extra sure to scrub any debug or error information that might reveal what is going on behind the scenes – this is typically where an attacker will try to find vulnerabilities first.
When a zero-day vulnerability is discovered, hackers will immediately try to find a way to exploit it. If your site leaks information about the technology you use, you could well become subject to automated attacks.
Protection
Disable the “Server” HTTP Header and Similar Headers
In your web server configuration, make sure to disable any HTTP response headers that reveal what server technology, language and version you are running.
Use Clean URLs
Try to avoid tell-tale file suffixes in URLs like .php, .asp and .jsp – implement clean URLs instead.
Ensure Cookie Parameters are Generic
Make sure that nothing is sent back in cookies that gives a clue about the technology stack. This includes tell-tale parameter names, which should be made as generic as possible.
Disable Client-Side Error Reporting
Most web server stacks allow verbose error reporting to be turned on when unexpected errors occur – meaning stack traces and routing information are printed in the HTML of the error page. Make sure this is disabled in your production environment. Log files and other error reporting systems are useful in your testing environment, but in production, error reporting should be restricted to the server-side.
Make sure unexpected errors return a generic HTTP 500 page. Depending on your technology stack, this may require explicitly catching unexpected exceptions thrown while handing web requests.
Sanitize Data Passed to the Client
Be sure that pages and AJAX responses only return the data needed. Database IDs should be obfuscated, if possible – and if you retain sensitive data for users, make sure it is only sent to the client-side in contexts where it is okay to be shared.
Obfuscate JavaScript
This will make your pages faster to load, and will also make it harder for an attacker to probe for client-side vulnerabilities.
Sanitize Template Files
Conduct code reviews and use static analysis tools to make sure sensitive data doesn’t end up in comments or dead code passed to the client.
Ensure Correct Configuration of Your Web Root Directory
Make sure to strictly separate public and configuration directories, and make sure everyone on your team knows the difference.
Code Samples
Python
Django
Django comes with a global_settings.py
file. Individual settings can be overridden by environment-specific configuration
files.
Configure the session ID parameter by setting SESSION_COOKIE_NAME
:
############
# SESSIONS #
############
# Cookie name. This can be whatever you want.
SESSION_COOKIE_NAME = 'session'
The verbosity of error reporting is controlled by the
DEBUG
flag in the configuration. A value of true prints stack traces on error
pages. A false value will return a safe, generic error page, and report
errors to administrators by email.
Ruby
Rails
The method of configuring the Server
header varies server-by-server,
so consult your documentation. The parameter used to identify sessions
can be defined in configuration:
Rails.application.config.session_store :cookie_store, key: 'id'
Rails comes packaged with sensible defaults for local, test, and production
environments, so as long as you make sure you are running the correct
config, error pages should not leak system information in production.
It’s common to implement more explicit debugging in non-production
environments by including various gems. Make sure these gems are only
included for :development
and :test
environments
in your Gemfile
.
The Rails Asset Pipeline makes it very easy to introduce JavaScript obfuscation with a single configuration change.
Java
Tomcat
Obscure the Server
header by editing the config file conf/server.xml
:
<Connector port="8080" server="Server" />
Customize the name of your session ID parameter by editing your web.xml
config:
<session-config>
<cookie-config>
<name>session</name>
</cookie-config>
</session-config>
Route unexpected errors to a page of your choosing be editing your web.xml
file:
<error-page>
<error-code>500</error-code>
<location>unexpected-error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>unexpected-error.jsp</location>
</error-page>
Make sure your custom error page only discloses detailed error information when it is safe to do so – i.e. in a non-production environment!
If you are using a default servlet, make sure it does not allow directory listings:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
.NET
By default, an ASP.NET stack returns quite a lot of information in the HTTP headers. See
here
for instructions on how disable the Server
header, and several other headers
that leak information.
To rename the session ID parameter from ASP.NET_SessionId
, modify your
web.config:
<system.web>
<sessionState cookieName="session" />
</system.web>
To disable debugging information in your production environment, make sure
your web.config
contains the following flag:
<configuration>
<compilation debug="false"/>
</configuration>
You will also need to set up your own custom error page, because the default error page gives a lot of error detail:
<customErrors mode="On" defaultRedirect="ErrorPageName.htm" />
See here for instructions for finding the “home” (web root) directory of your IIS server. Make sure the only assets under this directory are ones you want your users to see!
Further Reading
- How to Disable Directory Listing on Your Web Server
- Apache Tomcat 9 - Security Considerations
- Why is Source Code Disclosure Dangerous?
- UglifyJS – a JavaScript parser/compressor/beautifier.
- Closure Compiler, a popular JavaScript obfuscator.
- javascript-obfuscator, another popular JavaScript obfuscator.