Existe-t-il un moyen recommandé d'échapper aux caractères <
, >
, "
et &
lors de la génération de code HTML en langage clair Java? (Autre que faire manuellement ce qui suit, c'est).
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = source.replace("<", "<").replace("&", "&"); // ...
StringEscapeUtils à partir de Apache Commons Lang :
import static org.Apache.commons.lang.StringEscapeUtils.escapeHtml;
// ...
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = escapeHtml(source);
Pour version :
import static org.Apache.commons.lang3.StringEscapeUtils.escapeHtml4;
// ...
String escaped = escapeHtml4(source);
Une alternative à Apache Commons: Utilisez la méthode HtmlUtils.htmlEscape(String input)
de Spring .
Belle méthode courte:
public static String escapeHTML(String s) {
StringBuilder out = new StringBuilder(Math.max(16, s.length()));
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
out.append("&#");
out.append((int) c);
out.append(';');
} else {
out.append(c);
}
}
return out.toString();
}
Basé sur https://stackoverflow.com/a/8838023/1199155 (l'ampli y manque). Les quatre caractères cochés dans la clause if sont les seuls en dessous de 128, selon http://www.w3.org/TR/html4/sgml/entities.html
Il existe une version plus récente de bibliothèque Apache Commons Lang et utilise un nom de package différent (org.Apache.commons.lang3). La StringEscapeUtils
a maintenant différentes méthodes statiques pour échapper à différents types de documents ( http://commons.Apache.org/proper/commons-lang/javadocs/api-3.0/index.html ) Donc, pour échapper à la chaîne HTML version 4.0:
import static org.Apache.commons.lang3.StringEscapeUtils.escapeHtml4;
String output = escapeHtml4("The less than sign (<) and ampersand (&) must be escaped before using them in HTML");
Pour ceux qui utilisent Google Guava:
import com.google.common.html.HtmlEscapers;
[...]
String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = HtmlEscapers.htmlEscaper().escape(source);
Sur Android (API 16 ou supérieure), vous pouvez:
Html.escapeHtml(textToScape);
ou pour les API inférieures:
TextUtils.htmlEncode(textToScape);
Sois prudent avec ça. Un document HTML contient un certain nombre de "contextes" différents: à l'intérieur d'un élément, la valeur d'attribut citée, la valeur d'attribut non citée, l'attribut d'URL, javascript, CSS, etc. ceux-ci pour empêcher le Cross-Site Scripting (XSS). Consultez la page de contrôle de prévention OWASP XSS pour plus de détails sur chacun de ces contextes - https://www.owasp.org/index.php/XSS_ (Cross_Site_Scripting) _Prevention_Cheat_Sheet . Vous pouvez trouver des méthodes d'échappement pour chacun de ces contextes dans la bibliothèque OWASP ESAPI - https://github.com/ESAPI/esapi-Java-legacy .
Pour certaines raisons, HtmlUtils :
import org.springframework.web.util.HtmlUtils;
[...]
HtmlUtils.htmlEscapeDecimal("&"); //gives &
HtmlUtils.htmlEscape("&"); //gives &
Bien que @dfa answer of org.Apache.commons.lang.StringEscapeUtils.escapeHtml
soit Nice et que je l'utilisais dans le passé, il ne devrait pas être utilisé pour échapper des attributs HTML (ou XML) sinon les espaces seront normalisés (ce qui signifie que tous les caractères d’espace adjacents deviennent un seul espace).
Je le sais car des bogues ont été enregistrés dans ma bibliothèque (JATL) pour les attributs pour lesquels les espaces n'ont pas été préservés. J'ai donc un drop in (copier-coller) classe (dont j'en ai volé quelques-uns à JDOM) qui différencie l'échappement des attributs et du contenu de l'élément .
Bien que cela n'ait peut-être pas eu autant d'importance dans le passé (échappement d'attribut approprié), il est de plus en plus intéressant, étant donné l'utilisation de l'attribut data-
de HTML5.
org.Apache.commons.lang3.StringEscapeUtils est maintenant obsolète. Vous devez maintenant utiliser org.Apache.commons.text.StringEscapeUtils de
<dependency>
<groupId>org.Apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons.text.version}</version>
</dependency>