2017-08-30 1 views
0

Dans mon site, tout tag html d'une entrée d'utilisateur est échappé par htmlspecialchars, puis j'envoie des balises html + contenu d'utilisateur échappé comme une variable JSON en utilisant PHP json_encode, cela échappe à tous "as \", seulement ceux que j'ai mis le HTML parce que l'entrée de l'utilisateur est déjà échappée.Est-il nécessaire d'encoder du HTML dans JSON à HEX?

Cela fonctionne très bien, je n'ai eu aucun problème, je ne vois pas comment une attaque XSS serait possible, et j'ai essayé.

Mais je vois que Twitter et encode facebook pour HEX toutes les balises HTML, donc si je ferais la même chose je voudrais ajouter les options JSON_HEX_TAG JSON_HEX_AMP JSON_HEX_APOS JSON_HEX_QUOT-json_encode().

Alors pourquoi Twitter et Facebook font-ils cela et pourquoi? Je ne pouvais pas créer une erreur de sécurité.

+0

'sur un ancien navigateur' ... erm, Edge est ** pas ** un navigateur onlder –

+0

@Jaromanda Ce que je veux dire, c'est qu'il fonctionne bien dans tous les navigateurs que j'ai testé IE9 + Edge Firefox Chrome Opera. Je dis juste par curiosité, que si vous regardez le fichier JSON, si vous entrez dans les outils de développement et que vous effectuez une recherche sur l'onglet Réseau, le navigateur ne coloriera pas bien les variables qui ont "échappé comme \". Il fonctionne parfaitement sur Edge, donc je dis seulement comme une hypothèse, que peut-être le moteur de coloration n'est pas mis à jour et il fonctionne comme et vieux navigateur lirait le fichier JSON, juste deviner. – Vixxs

+0

donc, votre question ne concerne pas un problème avec le code, il s'agit de la console d'outils de développement pretty print? –

Répondre

0

Votre stratégie semble bien d'un point de vue XSS. L'encodage hexadécimal est peut-être pour supporter d'autres langages/jeux de caractères?

+0

Ce (Unicode multi-octets) est fait par défaut depuis PHP 5.4.0, donc je le fais aussi. Ils encodent des balises HTML, donc: < > & "'comme HEX, le" json_encode "par défaut n'échappe qu'à" as \ "il n'encode pas les balises HTML – Vixxs

0

Habituellement, vous devez échapper les parenthèses et les guillemets, car ils peuvent échapper au contexte html environnant. json_encode par lui-même n'est utile que si vous produisez un fichier '.js' sans html.

Les deux méthodes peuvent empêcher XSS, mais la différence est qu'elles produisent une sortie différente. htmlspecialchars convertit '<' en '& lt;' (une entité html) et le codage hexadécimal convertit '<' en '\ u003C' (séquence d'échappement littérale de chaîne JavaScript). Si vous envoyez des données à une variable JavaScript, alors vous voulez que le JavaScript en assure l'intégrité.

Dites que vous voulez envoyer le message «Un mois de temps» en JavaScript.

Avec un encodage hexadécimal, vous écrivez:

<script> 
    var input = <?php 
     $input = "One month's time"; 

     $input = json_encode($input, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); 

     echo $input; 
    ?>; 
    console.log(input); 
</script> 

et il sortira « de temps de un mois », comme vous voulez.

Avec htmlspecialchars, vous écrivez:

<script> 
    var input = <?php 
     $input = "One month's time"; 

     $input = htmlspecialchars($input, ENT_QUOTES, "utf-8"); 
     $input = json_encode($input); 

     echo $input; 
    ?>; 
    console.log(input); 
</script> 

et il sortira "Un mois & # 039; le temps", qui a corrompu les données. C'est parce qu'il est codé en HTML mais n'a pas été inséré directement dans un contexte HTML.

Vous devez utiliser le codage HTML si vous définissez une propriété innerHTML, ou similaire, mais pour empêcher XSS DOM, mais cela peut être fait avec JavaScript plutôt qu'avec PHP.