Il y a 14 ans -
Temps de lecture 10 minutes
SpringOne 2009 – Sécurisation d’Apache Tomcat
Depuis le rachat de Covalent en Janvier 2008, SpringSource est le premier contributeur au projet Apache Tomcat avec plus de 80% des commits ; Mark Thomas et Philip Thomas en sont les principaux acteurs.
Tomcat est la pierre angulaire de l’offre middleware de SpringSource aujourd’hui composée de tc Server, une version professionnelle Open Source de Tomcat et dm Server, un serveur OSGi (le format d’assemblage que SpringSource préfère aux classiques .war).
Mark Thomas a présenté lors de SpringOne 2009 : Securing Apache Tomcat For Your Environment les points essentiels sur ce sujet qui se décompose en trois thèmes : la confidentialité, l’intégrité et la disponibilité.
Planifier la correction des vulnérabilités
Même si les failles de sécurité sont extrêmement rares dans l’écosystème Java, il est nécessaire de se préparer à répondre à une vulnérabilité en ayant élaboré un plan d’application de correctifs. La réalité sera sûrement différente des plans, mais il est important d’avoir imaginé les rôles et responsabilités de chaque équipe (administrateurs, développement, support, recette, etc.) et de savoir quelle équipe fournira le chef de projet qui coordonnera tous les acteurs. Un plan de correction de vulnérabilités Tomcat comprendra typiquement les étapes suivantes :
- Prise de connaissance de la vulnérabilité : ces informations sont publiées sur le site web de Tomcat, diffusées sur les mailing lists Tomcat (une liste dédiée aux annonces de sécurité et de mises à jour sera bientôt disponible) ; un contrat de support Tomcat permettra aussi d’être averti. Il faut également identifier l’équipe (admin, dév, support, etc.) responsable de suivre ces informations.
- Lorsqu’une vulnérabilité est connue, il faut déterminer si elle s’applique à l’architecture mise en place (e.g. un problème AJP ne concernera pas les utilisateurs de mod_proxy_http, etc.) ; les équipes d’admin et de dév seront vraisemblablement impliquées dans cette étape. Un contrat de support pourra faciliter cette tâche.
- S’il s’avère nécessaire d’appliquer le correctif, l’équipe de développement réalisera les premiers tests de non-régression sur un poste de travail avant que l’équipe d’administrateurs installe le fix sur un environnement de validation (e.g. intégration ou pré-production) pour que les équipes de recette réalisent des tests de non-régression plus poussés.
- Une fois la non-régression confirmée par les équipes de recette, l’équipe d’administrateurs déploiera le correctif en production.
- Le chef de projet qui gère la correction d’une vulnérabilité de sécurité pourra à tout moment décider d’arrêter tout ou partie de l’application en production pour prévenir une attaque.
Ce type de plan pourrait sembler alarmiste ou excessif pour le monde Java mais il faut garder en tête que nous développons des applications critiques dont la compromission pourrait avoir des impacts autant financier que de notoriété.
Bonnes pratiques d’installation Tomcat
Permissions OS, JVM et réseau
- Pour limiter l’impact en cas d’attaque réussie, créer un utilisateur dédié à l’exécution des serveurs tomcat (e.g. ‘tomcat’) aux droits limités à l’arborescence de répertoires utilisés par Tomcat. On pourra compléter cette approche par la création d’un groupe ‘tomcat’ dont feront partie les utilisateurs qui auront accès en lecture seule aux fichiers de l’arborescence Tomcat. Sous Linux/Unix, cela correspond à une politique de répertoire
owner=rwx, group=r, other=none
. - En cas de doute sur la bienveillance des applications web déployées sur le serveur Tomcat, utiliser le Security Manager Java pour limiter les droits d’accès (fichiers, socket, etc.) de ces applications.
- Utiliser des firewalls aussi bien entrants que sortants. Si les premiers sont le plus souvent installés, il est hélas fréquent de ne pas avoir les seconds. Sans cela, du code malicieux pourra sans difficulté faire sortir sur Internet des informations sensibles ou télécharger des programmes malveillants (chevaux de Troie, etc.).
Applications par défaut
Il ne faut installer les applications fournies par défaut dans Tomcat que si elles sont utilisées :
- Supprimer les applications
docs
etexamples
. - Remplacer l’application ROOT par une version épurée (e.g. ROOT.war). Notez qui si vous ne spécifiez pas d’application ROOT, les appels à des URLs non définies par une des applications déployées retourneront un message « 400 Bad Request » qui surprendra beaucoup plus que le traditionnel « 404 Not Found ».
- Supprimer les applications
manager
etbalancer-manager
si vous reposez sur le classique déploiement d’applications par copie de fichier.
Realms
Les Realms fournis avec Tomcat avaient jusqu’à présent pour forte limitation de ne pas offrir de mécanisme de verrouillage des comptes utilisateurs et étaient donc exposés aux attaques par force brute. Tomcat 6.0.19 introduit un LockOutRealm qui offre ce verrouillage ainsi qu’un CombinedRealm qui permet de combiner des users déclarés dans plusieurs realms. Par ailleurs, les MemoryRealm et JDBCRealm ne devraient pas être utilisés en production respectivement parce que le premier ne permet pas de rechargement des users sans redémarrage et le second parce qu’il est limité à une seule connexion JDBC simultanée.
Shutdown Port, un reliquat des premières heures de Java
Le shutdown port servait pour les JVM inférieures à 1.3 qui ne supportaient pas les shutdownHook mais représente aujourd’hui une faille de sécurité : n’importe quel utilisateur connecté sur la machine peut arrêter le serveur Tomcat avec un simple telnet ; les mécanismes de permissions liés au propriétaire du processus sont ignorés.
Ce shutdown port doit être désactivé (server port="-1" ...
) au profit du classique kill Unix ou d’un service Windows . Désactiver ce mécanisme nécessite une adaptation du script catalina.sh
et, sur les plateformes linux/unix qui utilisent kill
, s’accompagne de la déclaration dans setenv.sh
de la variable CATALINA_PID
pour créer un fichier qui porte l’id du processus Tomcat.
Si vous ne pouvez désactiver le shutdown port, remplacez la commande d’arrêt par défaut « SHUTDOWN » par un mot secret imprédictible. Il n’est hélas pas possible de filtrer l’adresse IP de l’appelant.
Exemple (Shutdown port avec un commande d’arrêt imprédictible) :
Logs et audit
L’AccessLogValve doit être utilisée pour tracer les requêtes HTTP. On déclarera communément un fichier de log par host pour identifier le host saisi dans l’url d’appel qui, à la différence de l’URI, n’apparaît pas dans le fichier access_log. Si Tomcat est positionné derrière un load balancer ou un reverse proxy, il faut gérer le header X-Forwarded-For (voir « Tomcat – Adresse IP de l’internaute, load balancer, reverse proxy et header Http X-Forwarded-For« ).
Ces fichiers de log, au même titre que les logs applicatives, doivent être archivés.
Exemple (configuration d’un Access Log par Host) :
Filtrage des requêtes entrantes
Tomcat permet de filtrer les requêtes en fonction de l’adresse IP ou du host de l’appelant (respectivement RemoteAddrValve et RemoteHostValve). Le deuxième filtre connaît peu de scénarios d’utilisation. Comme pour l’AccessLogValve, si Tomcat est positionné derrière un load balancer ou un reverse proxy, il faut gérer le header X-Forwarded-For (voir infra « Adresse IP de l’internaute, reverse proxy et header Http X-Forwarded-For »). Exemple (Filtrage des IP appelantes) :
Protection des mots de passe présents dans la configuration
Tomcat a exclu la mise en oeuvre de mécanismes de protection des mots de passe saisis dans les fichiers de configuration au motif que ces mécanismes nécessitent l’utilisation d’un nouveau secret d’obfuscation qui devient alors difficile à protéger et conduirait donc à un problème de type « serpent qui se mord la queue ».
Nous corroborerons ce raisonnement remettant en cause les mécanismes de type « protection pour qu’on ne se souvienne pas du mot de passe en regardant par dessus l’épaule d’un administrateur » : si un mot de passe est vraiment compliqué (majuscules, minuscules, chiffres et caractères de ponctuation), il n’est pas mémorisable d’un simple coup d’oeil ; la génération de tels mots de passe est très simple avec les nombreux sites web qui offrent gratuitement ce service (e.g. PC Tools Secure Password Generator).
Limitations des déploiements d’applications
Tomcat offre le déploiement de nouvelles applications lorsque le serveur est déjà démarré. Cette fonctionnalité se désactive en positionnant la propriété autoDeploy
à false
:
Désactivation du déploiement d’applications lorsque Tomcat est démarré :
Tomcat permet également de déployer de nouvelles applications présentes sous le répertoire webapps
(nom de répertoire défini par la propriété appbase
). Cette fonctionnalité se désactive en positionnant la propriété deployOnStartup
à false
:
Désactivation du déploiement d’applications au démarrage de Tomcat :
Lorsque ces deux propriétés sont désactivées, seules les applications déclarées dans server.xml
sont déployées.
Par ailleurs, la propriété deployXML
permet, en la mettant à false
, de désactiver les éléments de configuration embarqués par les web applications dans le fichier /META-INF/context.xml
Protection contre les dénis de service
Les connecteurs Http et AJP intègrent une protection contre les dénis de service en limitant la taille des requêtes (attribut maxPostSize
dont la limite par défaut est de 2 Mo) et limitant la taille des requêtes lors d’authentification par certificat client ou formulaire géré par Tomcat (attribut maxSavePostSize
dont la limite par défaut est de 4 Ko). Cette limite s’applique au corps de la requête et pas aux uploads de fichiers dont la limitation est déléguée au framework qui gère l’upload. Par exemple, Apache Commons File Upload offre pour cela un paramètre maxSize.
Apache Httpd offre un mécanisme similaire avec la directive LimitRequestBody mais cette protection n’est pas activée par défaut.
Autres bonnes pratiques de sécurité
La taille d’un fichier server.xml
ne devrait pas dépasser un écran, il faut retirer ce qui est inutile (dans l’hypothèse où les applications ne sont pas déclarées dans ce fichier).
Si vous migrez de Tomcat 5.5 ou inférieur à Tomcat 6.0, il ne faut pas réutiliser les anciens fichiers server.xml mais en réécrire de nouveau, à partir du modèle standard livré avec Tomcat.
L’InvokerServlet doit rester désactivée. D’ailleurs, elle sera retirée de Tomcat 7. La [Default Servlet|http://tomcat.apache.org/tomcat-6.0-doc/default-servlet.html] doit conserver le paramètre readonly
à true
(désactivation des requêtes PUT
et DELETE
sur les contenus statiques) et le paramètre listings
à false
(désactivation de la liste des fichiers d’un répertoire).
La possibilité d’utiliser des request dispatchers inter web applications (attribut crossContext
) devrait rester désactivée comme l’autorisation d’accéder à des composants internes Tomcat depuis les web applications (attribut privileged
) et la possibilité d’utiliser des liens symboliques dans les web applications ( attribut allowLinking
). L’activation de cette dernière option exposerait le serveur à des risques de type directory traversal.
Pour aller plus loin
* Apache Tomcat Tips and Tricks from the Pros (webinar),
* Performance Tuning Apache Tomcat for Production (webinar),
* Performance Tuning for Apache Tomcat (slides de SpringOne 2009),
* The Center for Internet Security : CIS Apache Tomcat Server Benchmark v.1.0.0. 55 pages très instructives sur la sécurisation de Tomcat. Si vous avez aimé, regardez aussi CIS Apache Web Server 1.3.37/2.0.59/2.2.4 Benchmark v2.2.0.
11/05/2009 : prise en compte de la remarque d’Arnaud : « n’importe qui peut arrêter le serveur Tomcat avec un simple telnet » -> « n’importe quel utilisateur connecté sur la machine peut arrêter le serveur Tomcat avec un simple telnet ; les mécanismes de permissions liés au propriétaire du processus sont ignorés ».
27/01/2010 : ajout des références à « CIS Apache Tomcat Server Benchmark v.1.0.0 » et « CIS Apache Web Server 1.3.37/2.0.59/2.2.4 Benchmark v2.2.0 »
Commentaire
8 réponses pour " SpringOne 2009 – Sécurisation d’Apache Tomcat "
Published by Alexandre de Pellegrin , Il y a 14 ans
Comme d’habitude avec Cyrille, un excellent article qui déchire sa mémère. Et quand en plus Mark Thomas est de la partie, ça roxe carrément les poneys. Bravo et merci!
Published by Vanstals Thomas , Il y a 14 ans
Merci pour ce résumé complet. J’attendais les slides mais je n’en n’ai plus besoin.
Published by Cyrille Le Clerc , Il y a 14 ans
Merci pou vos encouragements. Nous avons encore plusieurs sujets de billets liés à SpringOne 2009. Nous nous y remettrons juste après la soirée Data Grid que nous animerons mardi 12 Mai au Paris JUG.
Nous avons notamment en tête :
Enfin, plein de beaux sujets mais avant, nous espérons vous voir à la soirée Data Grid au Paris JUG mardi 12 Mai ;-)
Cyrille (Xebia)
Published by arnaud , Il y a 14 ans
« n’importe qui peut arrêter le serveur Tomcat avec un simple telnet. »
Je ne crois pas, il faut au moins être sur la même machine:
http://marc.info/?l=tomcat-user&m=103176795905127&w=2
StandardServer.java:
// Set up a server socket to wait on
ServerSocket serverSocket = null;
try {
serverSocket =
new ServerSocket(port, 1,
InetAddress.getByName(« localhost »));
Published by Cyrille Le Clerc , Il y a 14 ans
Merci pour votre clarification Arnaud, je modifie le billet pour prendre en compte votre ajout :
« N’importe quel user connecté à la machine peut arrêter le serveur Tomcat avec un simple Telnet. Les mécanismes de permission liés au propriétaire du processus ne sont pas pris en compte ».
Cyrille (Xebia)
Published by Miguel , Il y a 14 ans
Précisions bien utiles pour tenter d’optimiser tomcat, qui de base se montre -hélas- trop peu adapté à un véritable environnement de prod.
Published by Cyrille Le Clerc , Il y a 14 ans
Merci Miguel pour cette ouverture !
Nous souhaitons depuis des mois rédiger une série de billet « Tomcat en production » qui partirait de la configuration Apache Httpd pour aller jusqu’à la supervision en passant par les logs, le load balancing, la haute disponibilité, le déploiement, la gestion de configuration, etc
Nous y retrouverions mod_proxy, mod_proxy_balancer, mod_expires, mod_cache, mod_deflate, les GUI /server-status & /balancer-manager, le connector Http11NioProtocol, le thread-pool tomcat, le layout avec séparation de TOMCAT_BASE et TOMCAT_HOME, la désactivation du java.util.logging.ConsoleHandler, le problème du passage de firewalls avec JMX, les solutions de monitoring comme Hyperic HQ et Nagios, les déploiements scriptés multi-phases, la mise sous SVN d’arborescences CATALINA_BASE, etc
Et nous pourrions conclure avec un produit Open Source Professionnel qui règle la plupart des besoins de productions non traités dans la version de base de Tomcat : SpringSource Tc Server.
Plein de choses à raconter, il ne reste plus qu’à se retrousser les manches pour rédiger ;-) .
Cyrille (Xebia)
Published by Cyrille Le Clerc , Il y a 13 ans
J’ai ajouté au billet des liens vers deux documents très intéressants du Center for Internet Security : CIS Apache Tomcat Server Benchmark v.1.0.0 et CIS Apache Web Server 1.3.37/2.0.59/2.2.4 Benchmark v2.2.0.
Cyrille (Xebia)