web-dev-qa-db-fra.com

Prévention des attaques CSRF, XSS et SQL Injection dans JSF

J'ai une application web construite sur JSF avec MySQL en tant que DB. J'ai déjà implémenté le code pour empêcher CSRF dans mon application.

Maintenant que mon framework sous-jacent est JSF, je suppose que je n'ai pas à gérer l'attaque XSS car elle est déjà gérée par UIComponent. Je n'utilise aucun JavaScript dans aucune des pages d'affichage. Même si j'utilise, ai-je vraiment besoin d'implémenter du code pour empêcher les attaques XSS?

Pour DB, nous utilisons des instructions préparées et des procédures stockées dans toutes les interactions DB.

Y a-t-il autre chose à gérer pour empêcher ces 3 attaques courantes? J'ai déjà parcouru le site OWASP et leur aide-mémoire .

Dois-je prendre soin de tout autre vecteur d'attaque potentiel?

54
AngelsandDemons

XSS

JSF est conçu pour avoir une prévention XSS intégrée. Vous pouvez réafficher en toute sécurité toutes les entrées contrôlées par l'utilisateur (en-têtes de demande (y compris les cookies!), Les paramètres de demande (également ceux qui sont enregistrés dans la base de données!) Et demander des corps (fichiers texte téléchargés, etc.) en utilisant n'importe quel composant JSF.

<h:outputText value="#{user.name}" />
<h:outputText value="#{user.name}" escape="true" />
<h:inputText value="#{user.name}" />
etc...

Notez que lorsque vous utilisez JSF 2.0 sur des Facelets, vous pouvez utiliser EL dans le texte du modèle comme ceci:

<p>Welcome, #{user.name}</p>

Cela sera également implicitement échappé. Vous n'avez pas nécessairement besoin de <h:outputText> ici.

Uniquement lorsque vous êtes explicitement unescaping entrée contrôlée par l'utilisateur utilisant escape="false":

<h:outputText value="#{user.name}" escape="false" />

alors vous avez un trou d'attaque XSS potentiel!

Si vous souhaitez réafficher les entrées contrôlées par l'utilisateur au format HTML dans lequel vous souhaitez autoriser uniquement un sous-ensemble spécifique de balises HTML comme <b>, <i>, <u>, etc., vous devez alors filtrer l'entrée par une liste blanche. L'analyseur HTML Jsoup est très tile à cet égard.

itemLabelEscaped bug dans Mojarra <2.2.6

Les anciennes versions de Mojarra avant 2.2.6 avait le bogue dans lequel <f:selectItems itemLabel> rend incorrectement le libellé non échappé lorsqu'il est fourni un List<T> via <f:selectItems var> au lieu de List<SelectItem> ou SelectItem[] comme valeur ( problème 314 ). En d'autres termes, si vous réaffichez les données contrôlées par l'utilisateur sous forme d'étiquettes d'élément via un List<T>, alors vous avez un trou XSS potentiel. Si la mise à niveau vers Mojarra 2.2.6 au moins n'est pas une option, vous devez définir explicitement l'attribut itemLabelEscaped sur true pour éviter cela.

<f:selectItems value="#{bean.entities}" var="entity" itemValue="#{entity}"
    itemLabel="#{entity.someUserControlledProperty}" itemLabelEscaped="true" />

CSRF

JSF 2.x a déjà intégré la prévention CSRF à la saveur de javax.faces.ViewState champ masqué dans le formulaire lors de l'utilisation de l'enregistrement de l'état côté serveur. Dans JSF 1.x, cette valeur était à savoir assez faible et trop facile à prévoir (elle n'a en fait jamais été conçue comme prévention CSRF). Dans JSF 2.0, cela a été amélioré en utilisant une valeur autogénérée longue et forte au lieu d'une valeur de séquence plutôt prévisible et en faisant ainsi une prévention CSRF robuste.

Dans JSF 2.2, cela peut même être encore amélioré en en faisant une partie obligatoire de la spécification JSF, ainsi qu'une clé AES configurable pour crypter l'état côté client, au cas où l'enregistrement de l'état côté client est activé. Voir aussi JSF spec issue 869 and Reusing ViewState value in other session (CSRF) . Nouveau dans JSF 2.2 est la protection CSRF sur les demandes GET par <protected-views> .

Uniquement lorsque vous utilisez des vues sans état comme dans <f:view transient="true">, ou il y a quelque part un trou d'attaque XSS dans l'application, alors vous avez un trou d'attaque CSRF potentiel.


Injection SQL

Ce n'est pas la responsabilité de JSF. Comment éviter cela dépend de l'API de persistance que vous utilisez (JDBC brut, JPA moderne ou bon vieux Hibernate), mais tout se résume à ce que vous ne devriez jamais concatène l'entrée contrôlée par l'utilisateur dans des chaînes SQL comme ceci

String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = md5(" + password + ")";
String jpql = "SELECT u FROM User u WHERE u.username = '" + username + "' AND u.password = md5('" + password + "')";

Imaginez ce qui se passerait si l'utilisateur final choisissait le nom suivant:

x'; DROP TABLE user; --

Vous devez toujours utiliser des requêtes paramétrées le cas échéant.

String sql = "SELECT * FROM user WHERE username = ? AND password = md5(?)";
String jpql = "SELECT u FROM User u WHERE u.username = ?1 AND u.password = md5(?2)";

En JDBC ordinaire, vous devez utiliser PreparedStatement pour remplir les valeurs des paramètres et en JPA (et Hibernate), l'objet Query propose des setters pour cela aussi.

106
BalusC

Je n'utilise aucun JavaScript dans aucune des pages d'affichage. Même si j'utilise, ai-je vraiment besoin d'implémenter du code pour contourner XSS Attack.

Vous pouvez être vulnérable à XSS même si vous n'utilisez pas JavaScript dans vos pages. XSS se produit lorsque vous incorporez du contenu contrôlé par un attaquant sans l'encoder correctement.

Chaque fois que vous faites quelque chose comme

response.write("<b>" + x + "</b>")

lorsqu'un attaquant peut provoquer que x contienne du code HTML contenant du JavaScript, vous êtes alors vulnérable à XSS.

La solution consiste généralement à ne pas écrire de grandes quantités de code. En règle générale, la solution consiste à coder $x et toute autre valeur contrôlée par un attaquant avant de les inclure dans le code HTML que vous générez.

response.write("<b>" + escapePlainTextToHtml(x) + "</b>")

Le filtrage ou la désinfection des entrées peut aider à fournir une couche de protection supplémentaire.

<shameless-plug>

Vous pouvez également utiliser un langage de modèle qui code automatiquement la sortie pour vous protéger contre XSS.

modèle de fermeture est l'une de ces options pour Java.

L'auto-échappement contextuel fonctionne en augmentant les modèles de fermeture pour encoder correctement chaque valeur dynamique en fonction du contexte dans lequel elle apparaît, se défendant ainsi contre les vulnérabilités XSS dans des valeurs contrôlées par un attaquant.

MODIFIER

Puisque vous utilisez JSF, vous devriez lire sur atténuation XSS dans JSF :

Texte de sortie d'échappement

<h:outputText/> et <h:outputLabel/> par défaut, l'attribut d'échappement est défini sur True. En utilisant cette balise pour afficher les sorties, vous pouvez atténuer la majorité de la vulnérabilité XSS.

SeamTextParser et <s:formattedText/>

Si vous souhaitez autoriser les utilisateurs à utiliser certaines des balises html de base pour personnaliser leurs entrées, JBoss Seam fournit un <s:formattedText/> tag qui autorise certaines balises html et styles de base spécifiés par les utilisateurs.

8
Mike Samuel