84 votes

Désinfecter/Réécrire du code HTML Côté Client

J'ai besoin d'afficher des ressources externes chargés via la croix de domaine de demandes et assurez-vous de n'afficher que les "sécuritaire" du contenu.

Pourrait utiliser du Prototype de Chaîne#stripScripts pour supprimer des blocs de script. Mais les gestionnaires comme onclick ou onerror sont toujours là.

Est-il une bibliothèque qui peut au moins

  • bande de blocs de script,
  • tuer DOM gestionnaires,
  • supprimer la liste noire des balises (par exemple: embed ou object).

Sont donc tout JavaScript liens connexes et des exemples là-bas?

113voto

Mike Samuel Points 54712

Shameless plug: voir http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/plugin/html-sanitizer.js pour un client html côté désinfectant qui a été complètement revu.

Il est dans la liste blanche, pas sur la liste noire, mais les listes blanches sont configurables par http://code.google.com/p/google-caja/wiki/CajaWhitelists


Si vous souhaitez supprimer toutes les balises, puis effectuez les opérations suivantes:

var tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*';

var tagOrComment = new RegExp(
    '<(?:'
    // Comment body.
    + '!--(?:(?:-*[^->])*--+|-?)'
    // Special "raw text" elements whose content should be elided.
    + '|script\\b' + tagBody + '>[\\s\\S]*?</script\\s*'
    + '|style\\b' + tagBody + '>[\\s\\S]*?</style\\s*'
    // Regular name
    + '|/?[a-z]'
    + tagBody
    + ')>',
    'gi');
function removeTags(html) {
  var oldHtml;
  do {
    oldHtml = html;
    html = html.replace(tagOrComment, '');
  } while (html !== oldHtml);
  return html.replace(/</g, '&lt;');
}

Les gens vont vous dire que vous pouvez créer un élément, et d'attribuer innerHTML , puis le innerText ou textContent, puis échapper à des entités. Ne pas le faire. Il est vulnérable à l'injection XSS depuis <img src=bogus onerror=alert(1337)> va exécuter l' onerror gestionnaire, même si le nœud n'est jamais attaché à la DOM.

40voto

Jeffery To Points 9225

Le Google Caja HTML désinfectant , peuvent être "prêt pour le web" par incorporée dans un web worker. Toutes les variables globales introduit par le désinfectant sera contenue dans le travailleur, en plus de la transformation a lieu dans son propre thread.

Pour les navigateurs qui ne prennent pas en charge des Web workers, nous pouvons utiliser une iframe comme un environnement distinct pour le désinfectant. Timothy Chien a un polyfill qui fait exactement cela, en utilisant des iframes pour simuler Web des Travailleurs, de sorte que cette partie est fait pour nous.

La Caja de projet a une page wiki sur la façon d'utiliser Caja autonome, côté client désinfectant:

  • La caisse de la source, puis de construire en cours d'exécution ant
  • Comprennent html-sanitizer-minified.js ou html-css-sanitizer-minified.js dans votre page
  • Appelez html_sanitize(...)

Le travailleur script a seulement besoin de suivre ces instructions:

importScripts('html-css-sanitizer-minified.js'); // or 'html-sanitizer-minified.js'

var urlTransformer, nameIdClassTransformer;

// customize if you need to filter URLs and/or ids/names/classes
urlTransformer = nameIdClassTransformer = function(s) { return s; };

// when we receive some HTML
self.onmessage = function(event) {
    // sanitize, then send the result back
    postMessage(html_sanitize(event.data, urlTransformer, nameIdClassTransformer));
};

(Un peu plus de code est nécessaire pour obtenir le simworker bibliothèque de travail, mais il n'est pas important de cette discussion.)

Démo: https://dl.dropbox.com/u/291406/html-sanitize/demo.html

22voto

Sean Edwards Points 1259

Ne faites jamais confiance le client. Si vous écrivez une application serveur, supposons que le client sera toujours soumettre insalubres, les données malveillantes. C'est une règle de pouce qui va vous garder hors de l'ennui. Si vous le pouvez, je vous conseille de faire toute la validation et à l'assainissement dans le code serveur, qui vous savez (à un degré raisonnable) ne sera pas trafiqué avec. Vous pourriez peut-être utiliser un serverside application web comme un proxy pour votre code côté client, qui extrait de la 3ème partie et ne l'assainissement avant de l'envoyer au client lui-même?

[edit] je suis désolé, j'ai mal compris la question. Cependant, je maintiens mon avis. Vos utilisateurs seront probablement plus en sécurité si vous désinfectez sur le serveur avant de l'envoyer à eux.

12voto

bobince Points 270740

Vous ne pouvez pas anticiper tous les possibles bizarre type de la malformation de balisage que certains navigateur, quelque part, peut-voyage à échapper à la mise à l'index, afin de ne pas la liste noire. Il y a beaucoup plus de structures que vous pouvez avoir besoin de supprimer que juste script/embed/objet et de gestionnaires.

Au lieu de tenter d'analyser le code HTML sur les éléments et attributs dans une hiérarchie, puis exécuter tous les noms d'élément et attribut contre un minimum possible de la liste blanche. Vérifiez également tout URL attributs de vous laisser face à une liste blanche (rappelez-vous il y a de plus dangereux protocoles de javascript:).

Si l'entrée est bien formée XHTML la première partie de la ci-dessus est beaucoup plus facile.

Comme toujours avec HTML epuration, si vous pouvez trouver tout autre moyen d'éviter de le faire, le faire à la place. Il y a beaucoup, beaucoup de failles potentielles. Si les principaux services web sont toujours à trouver des exploits de après ce de nombreuses années, ce qui vous fait penser que vous pouvez faire mieux?

5voto

neu-rah Points 1022
String.prototype.sanitizeHTML=function (white,black) {
   if (!white) white="b|i|p|br";//allowed tags
   if (!black) black="script|object|embed";//complete remove tags
   e=new RegExp("(<("+black+")[^>]*>.*</\\2>|(?!<[/]?("+white+")(\\s[^<]*>|[/]>|>))<[^<>]*>|(?!<[^<>\\s]+)\\s[^</>]+(?=[/>]))", "gi");
   return this.replace(e,"");
}

-liste noire -> complet supprimer la balise et le contenu

- "liste blanche" - > conserver les balises

-d'autres balises sont supprimées, mais le contenu de la balise est conservé

-tous les attributs de la liste blanche de la balise (ceux qui restent) sont supprimés

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X