4 nov. 2021 14:46:04 Thomas Dumont avatar

Points d'attention en terme de sécurité du code

Afin de sécuriser le code des applications face à des attaques malveillantes un certain nombre de points de vigilance sont à observer pour parer les différents types de vulnérabilité ci-dessous.

Cross Scripting

Ce type d'attaque consiste à ajouter du code HTML et surtout du Javascript exécutable à partir de données en entrée (ex : paramètre des requêtes). Ces attaques ne menacent pas l'intégrité du serveur, mais peuvent causer de sérieux préjudices aux utilisateurs. Elles sont donc à traiter avec la plus grande vigilance.

Lutece dispose de deux filtres, l'un sur le Front Office (jsp/site/*), l'autre sur le Back Office (jsp/admin/*), permettant d'interdire la liste des caractères utilisés pour ce type d'attaque.

Tout autre accès accès aux ressources de la WebApp doit être sécurisé.

La classe SecurityUtil de Lutece propose plusieurs méthode de vérification

  • containsCleanParameters( HttpServletRequest request ) contrôle tous les paramètres d'une requete
  • containsXssCharacters( request , strValue ) : contrôle si une valeur contient des caractères utilisés par les attaques XSS.

Dans la négative, ces deux méthodes tracent toutes les informations de la requête (Adresse IP, paramètres, ...) dans un fichier security.log. Les filtres évoqués, utilisant ces méthodes, tracent donc également toute tentative d'attaque.

Open Redirect

Ce type d'attaque permet de faire une redirection vers un site malveillant à partir de données en entrée.

Toutes les redirections faites par une application doivent donc vérifier que l'URI de destination est bien vérifiée et qu'en aucun cas elle provienne d'un paramètre non contrôlé.

Bean Manipulation

Il s’agit d’une vulnérabilité de la bibliothèque Apache BeanUtils BEANUTILS-463 corrigée en version 1.9.2. La version 5.1.2 de Lutece utilise cette version 1.9.2. La version 6.0.x de Lutece utilise cette version 1.9.3. Cette correction nécessite néanmoins une configuration complémentaire apportée dans les versions 5.1.6 et 6.0.1 https://dev.lutece.paris

Par ailleurs, cette vulnérabilité est bloquée par Tomcat à partir des versions 6.0.48, 7.0.73, 8.0.39, 8.5.8 comme indiqué dans la fiche : CVE-2016-6816

Path Manipulation

Ce type d'attaque consiste à modifier le chemin d'accès à un fichier à partir de données en entrée d'une requête. Les caractères utilisés sont "..", "/" "\" permettant ainsi de naviguer dans l'arborescence d'un système de fichiers.

A partir de Lutece 5.1.6 ou 6.0.1 une méthode containsPathManipulationChars de la classe SecurityUtil permet de détecter toute tentative de manipulation de chemin à partir de données en entrée. Les tentatives sont consignées dans le fichier security.log.

Log Forging

Ce type d'attaque consiste en la possibilité d’ajouter l’écriture de fausses informations dans les logs en les ajoutant à des données en entrée qui seraient loguées.

Toute données en entrée que l'on souhaiterait consigner dans un log de niveau autre que DEBUG doit être signalée comme une donnée provenant de l'utilisateur.

AppLogService.error( "User data : " + strUserData );

doit être sécurisé de la manière suivante :

AppLogService.error( "User data : "  + SecurityUtil.logForgingProtect( strUserData ));

XML External Entity Injection

La classe utilitaire XmlUtil est sécurisée par rapport à ce type d'attaque à partir de Lutece 5.1.6 et 6.0.1.

Unsafe Deserialization

Ce type d'attaque consiste en la modification d'un objet sérialisé (par les mécanismes standards de sérialisation de Java) qui a pour effet d'être exécutée au moment de la désérialisation de l'objet par la méthode readObject.

Pour ce prémunir de ce type d'attaque il faut vérifier que les classes désérialisées sont bien celles attendues.Ceci peut être réalisé grâce à la classe ValidatingObjectInputStream proposée par Apache Commons en lui indiquant la liste des classes acceptées comme dans l'exemple suivant.

ObjectInputStream objectInputStream = new ObjectInputStream( inputStream );
                ValidatingObjectInputStream objectInputStream = new ValidatingObjectInputStream( inputStream );
                objectInputStream.accept( MyObject.class );
                myObject = (MyObject) objectInputStream.readObject( );
                objectInputStream.close( );
NB : Si la classe de l'objet contient d'autres classes, elles devront également être ajoutées à la liste des classes acceptées.

Unreleased Resource

Si certaines ressources système ne sont pas correctement libérées, une personne malveillante peut réaliser une attaque de type DOS (Denial Of Service) .

Toutes les ressources doivent donc être correctement fermées notamment lorsqu'une exception interrompt le traitement. Pour cela il faut soit utiliser la clause finally soit la try-with-resource

finally 
{
        if( stream != null )
        {
            try
            {
                stream.close();
            }
            catch( IOException ex )
            {
                AppLogService.error( "Error closing the stream : " + ex.getMessage(), ex );
            }
        }
}

ou à partir de Lutece 6.0.1

finally
{
      safeClose( stream);
}

ou

try ( ACloseableStream stream = ... )
{
 ...
}