JavaScript Injection JSON évaluée


Exemple

Disons que chaque fois que quelqu'un visite une page de profil sur le site Web de Bob, l'URL suivante est récupérée:

https://example.com/api/users/1234/profiledata.json

Avec une réponse comme celle-ci:

{
    "name": "Bob",
    "description": "Likes pie & security holes."
}

Que ces données sont analysées et insérées:

var data = eval("(" + resp + ")");
document.getElementById("#name").innerText = data.name;
document.getElementById("#description").innerText = data.description;

Semble bon, non? Faux.

Que se passe-t-il si la description de quelqu'un est Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. ?

{
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
}

Et cela sera eval :

({
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
})

Si vous pensez que ce n'est pas un problème, collez-le dans votre console et voyez ce qui se passe.

L'atténuation

  • Utilisez JSON.parse au lieu de eval pour obtenir JSON. En général, n'utilisez pas eval et n'utilisez certainement pas eval avec quelque chose qu'un utilisateur pourrait contrôler. Eval crée un nouveau contexte d'exécution , créant un impact sur les performances .

  • Échapper correctement " et \ dans les données utilisateur avant de le mettre en JSON. Si vous venez d'échapper à la " , cela se produira:

    Hello! \"});alert(1);({
    

    Sera converti en:

    "Hello! \\"});alert(1);({"
    

    Oops. N'oubliez pas d'échapper à la fois à \ et " , ou utilisez simplement JSON.parse.