Comme la grande majorité des logiciels, Tomcat est installé dans une configuration par défaut, qui est un compromis entre l'utilisabilité et la sécurité. Pour un environnement de développement, cette configuration par défaut permet de faire fonctionner Tomcat immédiatement sans agir sur sa configuration et aux développeurs de l'utiliser en ayant quelques infos de débogage. Quelques points de vigilance sont à prendre en considération pour préparer son serveur Tomcat en production.
Ne pas exécuter le serveur Tomcat en root Supprimer les applications par défaut : manager, host-manager, ROOT, tomcat-docs, jsp-examples, servlets-examples, webdav,balancer
Dans $TOMCAT_HOME/conf/server.xml :
Désactiver l'autodeploy : <Host name="localhost" autoDeploy="false"> Désactiver tous les connecteurs inutiles
Dans WEB-INF/web.xml :
<error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page> <session-config> <cookie-config> <http-only>true</http-only> <secure>true</secure> </cookie-config> </session-config>
Dans $TOMCAT_HOME/conf/web.xml :
<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> <init-param> <param-name>showServerInfo</param-name> <param-value>false</param-name> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Selon les versions de Tomcat, les applications présentes par défaut ne sont pas toutes les mêmes. Toutes ces applications peuvent être supprimées. Dans le cas de Tomcat 9, il s'agit de supprimer dans $TOMCAT_HOME/webapps : docs, examples,host-manager, manager et ROOT.
La suppression de ROOT, docs et examples ne pose aucun problème. La suppression du manager, potentiellement plus contraignante, est recommandée pour différentes raisons :
Tomcat propose 3 connecteurs activés par défaut à l'écoute sur les ports 8005 (connecteur d'arrêt), 8080 (connecteur HTTP),8009 (connecteur AJP). Le connecteur HTTPS, sur le port 8443 par défaut, est désactivé. Il est recommandé d'activer les connecteurs utiles dans votre architecture et de désactiver les autres. Une architecture classique est de se reposer sur un reverse proxy (Apache par exemple) qui exposera l'application en HTTPS sur le port standard 443 et transférera les requêtes vers Tomcat (hébergé dans une zone réseau plus interne) sur son port 8080 (reverse proxy HTTP) ou 8009 (reverse proxy AJP). Celle-ci permet d'exposer son application sur le port HTTPS standard 443 sans nécessiter l'exécution du serveur Tomcat en root. Il est à noter que dans ce cas, les flux entre le reverse proxy et le serveur Tomcat ne seront pas chiffrés. Si cela est un besoin, le connecteur HTTPS devra être activé et configuré pour utilisé un certificat TLS stocké dans un keystore. D'une manière générale, la configuration du reverse proxy (et/ou load balancer selon les cas), doit s'assurer de ne pas exposer d'informations sensibles (ni le manager s'il est conservé, ni les arborescences WEB-INF des applications). Il est recommandé de désactiver (par suppression ou mise en commentaire dans $TOMCAT_HOME/server.xml) les connecteurs inutilisés de manière à réduire la surface d'attaque exposée.
Dans une approche offensive, après découverte d'une vulnérabilité, un attaquant peut s'appuyer sur les fonctionnalités de déploiement automatique pour installer une autre application sur le serveur (par exemple un Webshell). Pour limiter ces possibilités, la désactivation au minimum de l'autodeploy est recommandé. Cela impliquera que le déploiement d'une nouvelle application nécessitera un redémarrage du serveur Tomcat. La désactivation du déploiement au démarrage peut aussi être envisagée mais peut avoir des conséquences sur la stratégie de déploiement car cela nécessite que les contextes à déployer soient explicitement décrits dans le fichier $TOMCAT_HOME/conf/server.xml.
<Hostname="localhost" deployOnStartup="true|false" autoDeploy="false"><!-- deployOnStartup true ou false selon votre stratégie de déploiement (true par défaut) -->
Tomcat affiche par défaut des messages d'erreur présentant la pile d'appels (stacktrace) lors d'erreurs 500 et sa version qui représentent une fuite d'informations techniques utiles pour l'attaquant (et désagréables pour l'utilisateur).
La désactivation des informations de serveur se réalise aussi dans $TOMCAT_HOME/conf/web.xml :
<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> <init-param> <param-name>showServerInfo</param-name> <param-value>false</param-name> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Il est recommandé que la gestion des pages d'erreur soit configurée pour chaque application dans WEB-INF/web.xml enutilisant la balise <error-page> :
<error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page>
Cela évitera à Tomcat d'afficher sa page par défaut contenant diverses informations techniques mais dirigera l'utilisateur versune page spécifique intégrée à l'application.
L'entête de réponse HTTP Server indique généralement la technologie serveur qui a envoyé cette réponse. Selon la configuration, le serveur peut parfois retourner exactement sa technologie et sa version. Jusqu'à la version 6, Tomcat retournait Server: Apache-Coyote/1.1, désormais, il ne retourne plus l'entête de réponse Server (et la configuration par défaut est donc recommandée). Néanmoins, celle-ci peut se configurer dans les connecteurs HTTP :
<Connector port="8080"server="Raspberry" /><!-- server header is now Raspberry -->
Par défaut, le parcours des répertoires Web est désactivé depuis Tomcat 8. Cela peut se vérifier dans $TOMCAT_HOME/conf/web.xml :
<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> <!-- make sure this is false --> </init-param> <init-param> <param-name>showServerInfo</param-name> <param-value>false</param-name> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Les attributs Http-Only et Secure doivent être positionnés sur les cookies. Cela peut se faire dans la partie <session-config> dufichier web.xml.
<session-config> <cookie-config> <http-only>true</http-only> <secure>true</secure> </cookie-config> </session-config>
La commande “SHUTDOWN” passé en texte clair sur le port TCP 8005 permet d'éteindre le serveur. Il peut y avoir plusieurs moyens pour limiter les risques comme :
La désactivation du service étant largement préférée.
<Server port="-1" shutdown="SHUTDOWN">
Les recommandations listées ci-dessus constituent un niveau minimal de durcissement de configuration. De manière à simplifier la maintenance (mises à jour correctives), l'usage des paquets Tomcat et Java intégrés aux distributions est préférable. D'autres mesures telles que la configuration du SecurityManager, le blocage des déploiements au démarrage, la protection du service d'arrêt, le chiffrement des mots de passe ou la gestion des logs pourraient être évoquées. Vous trouverez d'autres infos sur la page de sécurisation de Tomcat de l'OWASP, sur ce site, ce site et sur la page de sécurisation de Tomcat de la fondation Apache.