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.
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.
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.
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.
Django comes with a
file. Individual settings can be overridden by environment-specific configuration
Configure the session ID parameter by setting
############ # SESSIONS # ############ # Cookie name. This can be whatever you want. SESSION_COOKIE_NAME = 'session'
The verbosity of error reporting is controlled by the
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.
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
Server header by editing the config file
<Connector port="8080" server="Server" />
Customize the name of your session ID parameter by editing your
<session-config> <cookie-config> <name>session</name> </cookie-config> </session-config>
Route unexpected errors to a page of your choosing be editing your
<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>
By default, an ASP.NET stack returns quite a lot of information in the HTTP headers. See
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
<system.web> <sessionState cookieName="session" /> </system.web>
To disable debugging information in your production environment, make sure
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!