S'échapper de sortie en toute sécurité pour le html et les champs de saisie
Dans mon application web, les utilisateurs peuvent entrer des données de texte. Ces données peuvent être communiquées aux autres utilisateurs, et l'auteur de l'original peut également revenir en arrière et modifier leurs données. Je suis à la recherche de la bonne façon de sortir en toute sécurité de ces données.
Je ne suis sql de désinfection sur le chemin, donc, tout est stocké comme il lit. Disons que j'ai "déjà-vu" dans la base de données. Ou, pour être plus extrême, un <script>
tag. Il est possible que cela soit valable, et même pas destiné à des fins malveillantes, d'entrée.
Je suis en utilisant htmlentities()
sur le moyen de sortir pour s'assurer que tout est échappé. Le problème, c'est que le html et les champs de saisie de traiter les choses différemment. Je veux faire en sorte qu'il est sûr en HTML, mais que l'auteur lors de l'édition du texte, voit exactement ce qu'ils ont saisies dans les champs de saisie. Je suis aussi à l'aide de jQuery pour remplir les champs du formulaire avec les données de façon dynamique.
Si je fais ceci:
<p><?=htmlentities("déjà vu");?></p>
<input type=text value="<?=htmlentities("déjà vu");?>">
La source de la page met déjà vu
dans les deux endroits (j'ai dû backtick ou que vous souhaitez voir "déjà-vu"!) Le problème est que la sortie dans les <p>
est correcte, mais l'entrée est juste échappé de texte. Si l'utilisateur soumet de nouveau à leur forme, ils échappement double et de la ruine de leur entrée.
Je sais que j'ai encore à désinfecter texte qui va dans le champ, sinon vous pouvez mettre fin à la valeur de devis et de faire de mauvaises choses. La seule solution que j'ai trouvé est celle-ci. Encore une fois, je suis en utilisant jQuery.
var temp = $("<div></div>").html("<?=htmlentities("déjà vu");?>");
$("input").val(temp.html());
Cela fonctionne, car il provoque la div pour lire l'échappé du texte en tant que caractères codés, et alors le jquery copies de ces caractères codés à la balise input, conservé correctement.
Donc ma question: est-ce toujours à l'abri, ou il y a un trou de sécurité quelque part? Et, plus important encore, est-ce la seule manière correcte de le faire? Ai-je raté quelque chose au sujet de comment html codage de caractères et les œuvres qui en font une question triviale à résoudre?
MODIFIER
C'est effectivement faux, j'ai simplifié mon exemple au point que cela ne fonctionne pas. Le problème est en fait parce que je suis à l'aide de jQuery val() pour insérer le texte dans le champ.
<input>
<script>$("input").val("<?=htmlentities("déjà vu");?>");</script>
La raison pour cela est que la forme est dynamique: l'utilisateur peut ajouter ou supprimer des champs, et donc ils sont générés après le chargement de la page.
Il semble donc que jQuery est de s'échapper de la données pour aller dans l'entrée, mais ce n'est pas tout à fait assez bon - si je ne fais rien de moi-même, un utilisateur peut toujours le mettre dans un </script>
tag, tuant mon code et de l'insertion de code malveillant. Mais il y a un autre argument à faire ici. Depuis que l'auteur original peut voir le texte dans une zone de saisie de toute façon, devrais-je même pas la peine? Fondamentalement, les seules personnes à qui ils pourraient exécuter une attaque XSS est contre eux-mêmes.
OriginalL'auteur Tesserex | 2010-06-30
Vous devez vous connecter pour publier un commentaire.
Je suis désolé mais je ne peut pas reproduire le comportement que vous décrivez. J'ai toujours utilisé des
htmlspecialchars()
(qui fait essentiellement la même tâche quehtmlentities()
) et il n'est jamais conduire à une sorte de double encodage. La source de la page montredéjà vu
dans les deux endroits (bien sûr! c'est le but!) mais le rendu de la page montre les valeurs appropriées et c'est ce qui a envoyé vers le serveur.Pouvez-vous poster un plein d'auto-contenue extrait de code qui présente ce genre de comportement?
Mise à jour: quelques tests de code:
Réponse à la mise à jour question
La
htmlentities()
fonction, comme son nom l'indique, est utilisé lors de la génération de la sortie HTML. C'est pourquoi il est de peu d'utilité dans votre deuxième exemple: JavaScript est pas HTML. C'est une langue avec sa propre syntaxe.Maintenant, le problème que vous voulez résoudre est de savoir comment générer une sortie qui suit ces deux règles:
Le plus proche de la fonction PHP pour le #1, je suis conscient de est json_encode(). Depuis syntaxe JSON est un sous-ensemble de JavaScript, si vous le nourrir avec une chaîne PHP il va sortir un JavaScript chaîne.
Comme sur le n ° 2, une fois que le navigateur entre dans un block JavaScript il s'attend à un
</script>
tag de la quitter. Le json_encode() fonction prend soin de cela et s'échappe correctement (<\/script>
).Mon révisé le code de test:
Remarque:
utf8_encode()
convertit de l'ISO-8859-1 à UTF-8 et il n'est pas nécessaire si vos données est déjà en UTF-8 (recommandé).OriginalL'auteur Álvaro González
Si vous avez juste besoin d'inverser le coder, alors vous pouvez utiliser html_entity_decode - http://www.php.net/manual/en/function.html-entity-decode.php.
Une autre possibilité est uniquement exécuter htmlentities à l'époque, le contenu sera affiché en tant que partie d'une page web. Sinon, garder la forme non codée de texte, tel que soumis ou chargé à partir de votre magasin de données.
OriginalL'auteur Frank
Je crois que c'est un problème avec la façon dont vous êtes en appliquant à la valeur vers l'entrée. Il s'affiche sous la forme codée, ce qui est logique, parce que c'est du Javascript, pas du HTML. Donc, ce que je voudrais proposer est d'écrire votre texte codé en tant que partie du balisage afin qu'il soit analysé de manière naturelle (par opposition à l'injection avec un script client). Depuis vos zones de texte ne sont pas facilement disponibles lorsque le serveur répond, vous pouvez utiliser un temporaire champ caché...
Elle sera analysée comme du bon vieux HTML, et lorsque vous essayez d'accéder à la valeur avec Javascript, il doit être décodé...
Je pense qu'il est sous-optimale dans la comparaison, car, avec votre solution de script client est encore en train de faire l'injection. Ce qui augmente les chances de script malveillant d'injection (parce que l'ensemble de la chaîne d'entrée va passer par l'interpréteur Javascript). Avec ma solution, la chaîne HTML est inclus dans le cadre naturel de la réponse HTML (et est dans un attribut, de sorte que le codage est nécessaire et attendue), puis Javascript, il sort après le fait. C'est plus propre, de l'OMI.
OriginalL'auteur Josh Stodola