Hide your Web stack
Hiding your web stack may be very useful to discourage most of the malicious users to try to do harm on your website. We’re going to list a few measures we can take to hide these informations from a malicious user who could take advantage of them.
Let’s say we’re running a website using Symfony2 on a classic LAMP/LEMP stack (the “E” is for (e)nginx). We’re going to use the Symfony2 Standard Edition with the AcmeDemoBundle unremoved (and loaded even in production) as an application example.
We’ll go from the top (the Symfony framework) to the bottom (our web server).
##Tools
There is a good Chrome Extension called Wappalyzer that can gather indications from a page URL, header’s, etc… to tell which technologies it’s using. It may be helpful to measure the progress our app is making through complete anonymousness.
Section intitulée anonymize-symfony2Anonymize Symfony2
Section intitulée skipping-the-obviousSkipping the obvious
Change the default favicon, do not deploy the app_dev.php
nor the config.php
in production, customize error 404 and 50x pages…
Section intitulée the-default-web-assetsThe default web assets
Public assets packaged with the application, like the stylesheets and the images used by the Web Debug Toolbar are of no use in production and shouldn’t be deployed.
Accessing a particular file like /bundles/framework/css/exception.css
which has a rich history on Github could help determine the version of Symfony2 used by our application.
We can either configure our webserver to serve 404 pages for URLs starting with /bundles (if we use Assetic, see below) or choose to not deploy them.
Section intitulée our-own-public-assetsOur own public assets
Let’s say our AcmeDemoBundle has a few assets on its own: a demo.css
and a main.js
files.
If we don’t use Assetic, our main.js
file may be included like this:
<script src="{{ asset('/bundles/acmedemo/js/main.js') }}" type="text/javascript"></script>
effectively displaying:
<script src="/bundles/acmedemo/js/main.js" type="text/javascript"></script>
The use of the folder hierarchy /bundles/bundlename/js/...
is pretty characteristic of the Symfony2 framework (and may also leak infos about the logical organization of your application).
The best way to avoid this is to use Assetic which allows us to compile a list of *.js
into one (idem for *.css
files).
With this syntax, all of our *.js
files are combined and served from the standard URL /js/main.js
:
{% javascripts '@AcmeDemoBundle/Resources/public/js/*' output='js/main.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
We can do the same for *.css
files.
There is no easy way to do the same with images: the AssetsInstallCommand
hardcodes the prefix url to /bundles/acmedemo
. It uses the Bundle::getName()
method which is final, meaning we can’t override the “acmedemo” part.
If we have access to our webserver config, we can rewrite the /bundles
part in /media
for instance.
With Apache:
RewriteRule ^/media /bundles
With nginx:
rewrite ^/media/(.*)$ /bundles/$1 last;
Section intitulée make-php-keep-a-low-profileMake PHP keep a low profile
Section intitulée change-the-default-cookie-nameChange the default cookie name
By default the cookie is named PHPSESSID
. We can change that by editing the config.yml file like this:
framework:
session:
name: acmedemo
Section intitulée remove-unnecessary-http-headersRemove unnecessary HTTP headers
PHP advertises itself through the HTTP header X-Powered-By
, we can change that by adding
expose_php = off
to our php.ini
config file.
Section intitulée hide-app-phpHide app.php
In most configurations, even if /
is rewritten into /app.php
, we can still access /app.php
directly. Most frameworks name their front controller index.php
so this could be a good indication that our app is running Symfony2. We could rename app.php
or if we want to completely hide the fact that we’re running PHP, we need to tell Apache or nginx to serve a 404 if someone access /app.php
directly.
Section intitulée keep-apache-or-nginx-quietKeep Apache or nginx quiet
Section intitulée remove-unnecessary-http-headersRemove unnecessary HTTP headers
Nginx advertises its name and version with the HTTP header Server. You can remove the version with:
server_tokens off
in the nginx.conf
file but if it’s not enough for you, you can modify the sources and recompile nginx to get rid of the remaininx “nginx” string as described here.
The same modification can be achieved with Apache by setting the following directive in the /etc/apache2/conf.d/security
file:
ServerTokens Prod
With Apache, there even is a module, mod_security that allows us to set the Server header to anything we want through the SecServerSignature
option.
Another way to achieve this would be to install a reverse-proxy like Varnish that allows you to manipulate headers freely and the server signature in particular.
Section intitulée customize-error-pagesCustomize error pages
Error pages are a simple way when not customized to detect the webserver in use.
You can either remove sensitive informations by setting ServerSignature
to off
in the /etc/apache2/conf.d/security
file or make apache serve custom 404 and 50x pages.
With nginx, setting server_tokens
to off hides nginx version in all visible places.
##nConclusion
At the end of day, a webserver is what it is and there may be no easy way to absolutely hide its nature from malicious users but this is where hackers often start and these measures can be a good starting point to harden your web app.
Commentaires et discussions
Ces clients ont profité de notre expertise
JoliCode accompagne l’équipe technique Dayuse dans l’optimisation des performances de sa plateforme. Nous sommes intervenus sur différents sujets : La fonctionnalité de recherche d’hôtels, en remplaçant MongoDB et Algolia par Redis et Elasticsearch. La mise en place d’un workflow de réservation, la migration d’un site en Twig vers une SPA à base de…
Dans le cadre d’une refonte complète de son architecture Web, le journal en ligne Mediapart a sollicité l’expertise de JoliCode afin d’accompagner ses équipes. Mediapart.fr est un des rares journaux 100% en ligne qui n’appartient qu’à ses lecteurs qui amène un fort traffic authentifiés et donc difficilement cachable. Pour effectuer cette migration, …
Nous avons réalisé différentes applications métier à l’aide de technologies comme Symfony2 et Titanium. Arianespace s’est appuyé sur l’expertise reconnue de JoliCode pour mettre en place des applications sur mesure, testées et réalisées avec un haut niveau de qualité.