Quel est le meilleur moyen de gérer le contenu HTML généré par l'utilisateur qui sera visualisé par le public?

StackOverflow https://stackoverflow.com/questions/1608758

  •  05-07-2019
  •  | 
  •  

Question

Dans mon application Web, j'autorise le contenu publié par l'utilisateur à des fins de consommation publique similaire à Stackoverflow.

Quelle est la meilleure pratique pour gérer cela?

Mes étapes actuelles de gestion du contenu généré par l'utilisateur sont les suivantes:

  1. J'utilise MarkItUp pour autoriser les utilisateurs un moyen facile de formater leur code HTML.

  2. Après qu'un utilisateur l'ait soumis changements, je le lance via un HTML Désinfectant (faites défiler jusqu’à la bottem) qui utilise une liste blanche approche.

  3. Si le processus de désinfection a supprimé tout contenu créé par l'utilisateur I ne pas enregistrer le contenu. J'ai alors Retourner le contenu modifié avec un message d'avertissement, "Certains sont illégaux les balises de contenu ont été détectées et retiré double vérifier votre travail et Réessayez. "

  4. Si le contenu passe par le processus de désinfection proprement, je sauve le contenu HTML brut à la base de données.

  5. Lors du rendu au client, je viens de passer le HTML brut de la base de données à la page.

Était-ce utile?

La solution

C'est une approche tout à fait raisonnable. Pour des applications typiques, cela sera tout à fait suffisant.

La partie la plus délicate du HTML brut de liste blanche est l'attribut style et embed / objet . Il y a des raisons légitimes pour lesquelles une personne pourrait vouloir insérer des styles CSS dans un bloc de texte formaté, par ailleurs non fiable, ou dans une vidéo YouTube intégrée. Ce problème se pose le plus souvent avec les flux. Vous ne pouvez pas faire confiance au bloc de texte arbitraire contenu dans une entrée de fil, mais vous ne voulez pas supprimer, par exemple, la coloration syntaxique CSS ou la vidéo flash, car cela changerait fondamentalement le contenu et dérouterait potentiellement toute personne qui le lit. Parce que CSS peut contenir des choses dangereuses comme des comportements dans IE, vous devrez peut-être analyser le CSS si vous décidez de laisser l'attribut style rester en mémoire. Et avec embed / objet vous devrez peut-être mettre en liste blanche les noms d'hôtes.

Addenda:

Dans le pire des cas, le HTML échappant à tout ce qui est en vue peut entraîner une expérience utilisateur très médiocre. Il est bien préférable d'utiliser un analyseur HTML5 pour parcourir le DOM avec votre liste blanche. Ceci est beaucoup plus flexible quant à la manière dont vous présentez la sortie assainie à vos utilisateurs. Vous pouvez même faire des choses comme:

<div class="sanitized">
  <div class="notice">
    This was sanitized for security reasons.
  </div>
  <div class="raw"><pre>
    &lt;script&gt;alert("XSS!");&lt;/script&gt;
  </pre></div>
</div>

Cachez ensuite le contenu .raw avec CSS et utilisez jQuery pour lier un gestionnaire de clics au .sanitized div qui bascule entre < code> .raw et .notice :

CSS:

.raw {
  display: none;
}

jQuery:

$('.sanitized').click(function() {
  $(this).find('.notice').toggle();
  $(this).find('.sanitized').toggle();
});

Autres conseils

La liste blanche est un bon coup. Toute solution de liste noire a tendance à laisser passer plus que prévu, car vous ne pouvez tout simplement pas penser à tout. J'ai déjà vu des exemples d'utilisation de listes noires (par exemple, The Code Project). S'ils parviennent à tout intercepter, ils entraînent toujours des problèmes supplémentaires, tels que le remplacement de caractères dans le code afin qu'il ne puisse pas être utilisé sans le restaurer manuellement. .

La méthode la plus sûre serait:

  1. HTML code tout le texte.

  2. Faites correspondre un ensemble de balises et d'attributs autorisés et décodez-les.

En utilisant une expression régulière, vous pouvez même exiger que chaque balise d'ouverture comporte une balise de fermeture, de sorte qu'une balise non fermée ne puisse pas gâcher la page.

Vous devriez être capable de faire cela en quelque chose comme dix lignes de code, le code auquel vous avez lié semble trop compliqué.

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