Question

Je souhaite empêcher les attaques XSS dans mon application Web.J'ai trouvé que le codage HTML de la sortie peut vraiment empêcher les attaques XSS.Maintenant, le problème est de savoir comment encoder en HTML chaque sortie de mon application ?Y a-t-il un moyen d'automatiser cela ?

J'apprécie les réponses pour JSP, ASP.net et PHP.

Était-ce utile?

La solution

Vous ne voulez pas encoder tout le HTML, vous souhaitez uniquement encoder en HTML toute entrée utilisateur que vous produisez.

Pour PHP : entités html et caractères spéciaux html

Autres conseils

Une chose que tu je ne devrais pas faire est de filtrer les données d'entrée au fur et à mesure qu'elles arrivent.Les gens suggèrent souvent cette solution, car c'est la solution la plus simple, mais cela entraîne des problèmes.

Les données d'entrée peuvent être envoyées à plusieurs endroits, en plus d'être sorties au format HTML.Il peut par exemple être stocké dans une base de données.Les règles de filtrage des données envoyées à une base de données sont très différentes des règles de filtrage de la sortie HTML.Si vous encodez tout en HTML lors de l'entrée, vous vous retrouverez avec du HTML dans votre base de données.(C'est aussi pourquoi la fonctionnalité "citations magiques" de PHP est une mauvaise idée.)

Vous ne pouvez pas anticiper tous les endroits où vos données d'entrée voyageront.L'approche sûre consiste à préparer les données juste avant c'est envoyé quelque part.Si vous l'envoyez vers une base de données, échappez aux guillemets simples.Si vous produisez du HTML, échappez aux entités HTML.Et une fois envoyé quelque part, si vous avez encore besoin de travailler avec les données, utilisez la version originale non échappée.

Cela demande plus de travail, mais vous pouvez le réduire en utilisant des moteurs de modèles ou des bibliothèques.

Pour les JSP, vous pouvez avoir le gâteau et le manger aussi, avec la balise c:out, qui échappe au XML par défaut.Cela signifie que vous pouvez lier vos propriétés en tant qu'éléments bruts :

<input name="someName.someProperty" value="<c:out value='${someName.someProperty}' />" />

Lorsqu'il est lié à une chaîne, someName.someProperty contiendra l'entrée XML, mais lors de sa sortie sur la page, il sera automatiquement échappé pour fournir les entités XML.Ceci est particulièrement utile pour les liens de validation de page.

Une bonne façon d'échapper à toutes les entrées de l'utilisateur consiste à écrire un modificateur pour smarty qui échappe à toutes les variables transmises au modèle ;sauf pour ceux auxquels |unescape est attaché.De cette façon, vous accordez uniquement l’accès HTML aux éléments auxquels vous donnez explicitement accès.

Je n'ai plus ce modificateur ;mais à peu près la même version peut être trouvée ici :

http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html

Dans la nouvelle version de Django 1.0, cela fonctionne exactement de la même manière, Jay :)

Ma préférence personnelle est d'encoder avec diligence rien cela vient de la base de données, de la couche métier ou de l'utilisateur.

Dans ASP.Net, cela se fait en utilisant Server.HtmlEncode(string) .

La raison pour laquelle vous encodez ainsi quoi que ce soit est que même les propriétés que vous pourriez supposer être booléennes ou numériques pourraient contenir du code malveillant (par exemple, les valeurs des cases à cocher, si elles ne sont pas effectuées correctement, pourraient revenir sous forme de chaînes.Si vous ne les codez pas avant d'envoyer le résultat à l'utilisateur, vous disposez d'une vulnérabilité).

Vous pouvez envelopper echo / print etc.dans vos propres méthodes que vous pouvez ensuite utiliser pour échapper à la sortie.c'est à dire.au lieu de

echo "blah";

utiliser

myecho('blah');

vous pourriez même avoir un deuxième paramètre qui désactive l'échappement si vous en avez besoin.

Dans un projet, nous avions un mode débogage dans nos fonctions de sortie qui rendait invisible tout le texte de sortie passant par notre méthode.Nous avons alors su que tout ce qui restait sur l'écran n'avait pas échappé !C'était très utile pour retrouver ces vilains morceaux non échappés :)

Si vous encodez réellement chaque sortie en HTML, l'utilisateur verra le texte brut de <html>au lieu d'une application Web fonctionnelle.

MODIFIER:Si vous encodez en HTML chaque entrée, vous aurez du mal à accepter un mot de passe externe contenant < etc.

La seule façon de réellement vous protéger contre ce type d’attaque est de filtrer rigoureusement toutes les entrées que vous acceptez, spécifiquement (mais pas exclusivement) provenant des zones publiques de votre application.Je vous recommande de jeter un oeil à celui de Daniel Morris Classe de filtrage PHP (une solution complète) et aussi le Zend_Filter package (une collection de classes que vous pouvez utiliser pour créer votre propre filtre).

PHP est mon langage de prédilection en matière de développement Web, donc je m'excuse pour le parti pris de ma réponse.

Kieran.

OWASP dispose d'une API intéressante pour encoder la sortie HTML, soit pour l'utiliser comme texte HTML (par ex.paragraphe ou <textarea> contenu) ou comme valeur d'un attribut (par ex.pour <input> balises après avoir rejeté un formulaire) :

encodeForHTML($input) // Encode data for use in HTML using HTML entity encoding
encodeForHTMLAttribute($input) // Encode data for use in HTML attributes.

Le projet (la version PHP) est hébergé sous http://code.google.com/p/owasp-esapi-php/ et est également disponible pour certaines autres langues, par ex..FILET.

N'oubliez pas que vous devez encoder tout (pas seulement la saisie de l'utilisateur), et aussi tard que possible (pas lors du stockage dans la base de données mais lors de la sortie de la réponse HTTP).

L'encodage de sortie est de loin la meilleure défense.La validation des entrées est excellente pour de nombreuses raisons, mais pas pour une défense à 100 %.Si une base de données est infectée par XSS via une attaque (c'est-à-direASPROX), une erreur ou une validation d'entrée malveillante ne fait rien.L'encodage de sortie fonctionnera toujours.

il y avait un bon essai de Joel sur les logiciels (faire paraître un mauvais code faux, je pense, je suis sur mon téléphone sinon j'aurais une URL pour vous) qui couvrait l'utilisation correcte de la notation hongroise.La version courte ressemblerait à ceci :

Var dsFirstName, uhsFirstName : String;

Begin

uhsFirstName := request.queryfields.value['firstname'];

dsFirstName := dsHtmlToDB(uhsFirstName);

En gros, préfixez vos variables avec quelque chose comme "nous" pour une chaîne dangereuse, "ds" pour la sécurité des bases de données, "hs" pour HTML sécurisé.Vous voulez uniquement encoder et décoder là où vous en avez réellement besoin, pas tout.Mais en utilisant des préfixes qui déduisent une signification utile en regardant votre code, vous verrez très rapidement si quelque chose ne va pas.Et vous aurez de toute façon besoin de différentes fonctions d’encodage/décodage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top