2017-03-31 4 views
0

Je tourne ici en dernier recours. J'ai parcouru google et j'ai de la difficulté à trouver une solution. J'ai un formulaire avec un élément textarea qui vous permet de taper html dans la zone et il affichera le balisage HTML en cours de frappe si vous avez activé le mode de prévisualisation. Pas trop différent de la façon dont StackOverflow affiche l'aperçu ci-dessous un nouveau message.Comment rendre un aperçu en direct HTML textarea sûr contre HTML/Script Injection

Cependant, j'ai récemment découvert que ma fonctionnalité a une vulnérabilité. Tout ce que je suis arrivé à faire est de taper quelque chose comme:

</textarea> 
    <script>alert("Hello World!");</script> 
<textarea style="display: none;"> 

Et non seulement cette course à l'intérieur du textarea en direct, si vous enregistrez le formulaire et reload ces données sur une autre page ce code exécute toujours dans la zone de texte sur ladite page différente, mais à l'insu de l'utilisateur; à eux tout le voir est un textarea (s'il n'y a pas d'alerte évidemment).

J'ai trouvé cet article; Live preview of textarea input with javascript html, et j'ai tenté de refactoriser mon JS à la réponse acceptée, car j'ai remarqué que je ne pouvais pas écrire une balise de script dans l'exemple JSFiddle, mais peut-être que JSFiddle bloquait ce comportement, mais je ne pouvais pas le faire fichier.

Ces quelques lignes est ce que j'utilise pour vivre rendre le balisage HTML:

$(".main").on("keyup", "#actualTextArea", function() { 
    $('#previewTextArea').html($('#actualTextArea').val()); 
}); 

$(".main").on("keydown", "#actualTextArea", function() { 
    $('#previewTextArea').html($('#actualTextArea').val()); 
}); 

Est-il possible, cela peut être refactorisé il est sûr? Ma seule idée pour le moment est d'effacer la prévisualisation en direct et d'utiliser une bascule on/off et de l'encoder, mais je pense vraiment que c'est une fonctionnalité intéressante et que je voudrais la garder en ligne au lieu de basculer. Y a-t-il un moyen de "l'encoder en direct" ou d'échapper à certaines étiquettes ou quelque chose?

Répondre

0

Edit: En fait, je pense que cette solution est un peu nettoyeur, et rend le code ci-dessous inutile. Dans la page de vélocité, tout ce qui est nécessaire est de profiter du framework Spring. Donc, je remplace le textarea avec cela comme si:

#springBindEscaped("myJavaObj.textAreaText" true) 
<textarea id="actualTextArea" name="${status.expression}" class="myClass" rows="10" cols="120">$!status.value</textarea> 

Ce jumelé avec une validation de Java back-end et il finit par être une solution beaucoup plus propre.

Mais si vous voulez une solution non-printemps/vitesse, cela fonctionne ci-dessous très bien


Je bricolé une solution rapide comme mon principal objectif est d'éliminer la possibilité pour les autres d'exécuter des scripts facilement . Ce n'est pas idéal, et je "m ne prétend pas que ce soit la meilleure réponse, donc si quelqu'un trouve une meilleure solution, s'il vous plaît faire part j'ai créé une. « Fonction Hygiénique » comme ceci:

function sanitize(text){ 
    var sanitized = text.replace("<script>", ""); 
    sanitized = sanitized.replace("</script>", ""); 
    return sanitized; 
} 

Puis les deux précédents gestionnaires d'événements ressemblent maintenant:

$(".main").on("keyup", "#actualTextArea", function() { 
    var textAreaMarkup = $('#actualTextArea').val(); 
    var sanitizedMarkup = sanitize(textAreaMarkup); 
    $('#actualTextArea').val(sanitizedMarkup); 
    $('#previewTextArea').html(sanitizedMarkup); 
}); 

// This one can remain unchanged and infact needs to be 
// If it's the same as above it will wipe the text area 
// on a highlight-backspace 
$(".main").on("keydown", "#actualTextArea", function() { 
    $('#previewTextArea').html($('#actualTextArea').val()); 
}); 

avec l'assainissement Java côté pour éviter quelque chose de néfaste étant stocké dans la base de données, cela sert mon but, mais je suis très ouvert à une meilleure solution si elle existe.

0

Pour assainir l'aperçu de votre zone de texte suffit simplement de remplacer le < et > avec leurs équivalents de code de caractère html:

function showPreview() 
 
{ 
 
    var value = $('#writer').val().trim(); 
 
    value = value.replace("<", "&lt;"); 
 
    value = value.replace(">", "&gt;"); 
 
    $('#preview').html(value); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<textarea id="writer" onInput="showPreview();"> 
 
</textarea> 
 
<br/> 
 
<hr/> 
 
<div id="preview"> 
 
</div>

+0

Cela ne protège pas contre la vulnérabilité que j'ai partagé ci-dessus ... :(J'essaie d'empêcher l'exécution des balises de script. –