web-dev-qa-db-ja.com

JavaでHTMLをエスケープするための推奨方法

プレーンなJavaコードでHTMLを出力するときに<>"および&の文字をエスケープするための推奨される方法はありますか? (手作業で以下のことをするのではなく).

String source = "The less than sign (<) and ampersand (&) must be escaped before using them in HTML";
String escaped = source.replace("<", "&lt;").replace("&", "&amp;"); // ...
239
Ben Lings

StringEscapeUtils from 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);

バージョン の場合:

import static org.Apache.commons.lang3.StringEscapeUtils.escapeHtml4;
// ...
String escaped = escapeHtml4(source);
249
dfa

Apache Commonsに代わるものです。 SpringHtmlUtils.htmlEscape(String input)メソッドを使用してください。

120
Adamski

素敵な短い方法:

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();
}

に基づいて https://stackoverflow.com/a/8838023/1199155 (アンプはそこにありません)。 http://www.w3.org/TR/html4/sgml/entities.html によると、if節でチェックされる4文字は128以下の唯一の文字です。

51
Bruno Eberhard

新しいバージョンの Apache Commons Lang library があり、それは異なるパッケージ名(org.Apache.commons.lang3)を使用しています。 StringEscapeUtilsは、さまざまな種類のドキュメントをエスケープするための静的メソッドが異なります( http://commons.Apache.org/proper/commons-lang/javadocs/api-3.0/index.html )。 HTMLバージョン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");
45
Martin Dimitrov

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);
38
okrasz

Android(API 16以上)では、次のことが可能です。

Html.escapeHtml(textToScape);

または下位のAPIの場合:

TextUtils.htmlEncode(textToScape);
38
OriolJ

これに注意してください。 HTML文書内には、さまざまな「コンテキスト」があります。要素内、引用符で囲まれた属性値、引用符で囲まれていない属性値、URL属性、javascript、CSSなど...それぞれに異なるエンコーディング方法を使用する必要があります。これらはクロスサイトスクリプティング(XSS)を防ぐためのものです。これらの各コンテキストの詳細については、OWASP XSS防止チートシートを参照してください - https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet 。 OWASP ESAPIライブラリ - https://github.com/ESAPI/esapi-Java-legacy で、これらの各コンテキストのエスケープ方法を見つけることができます。

37
Jeff Williams

いくつかの目的のために、 HtmlUtils

import org.springframework.web.util.HtmlUtils;
[...]
HtmlUtils.htmlEscapeDecimal("&")` //gives &#38;
HtmlUtils.htmlEscape("&")` //gives &amp;
14
AUU

org.Apache.commons.lang.StringEscapeUtils.escapeHtmlの@dfa答えはいいですし、私は過去にそれを使っていましたが、HTML(またはXML)属性をエスケープするために使うべきではありません。正規化されます(すべての隣接する空白文字が単一のスペースになることを意味します)。

空白が保存されていない属性について、私のライブラリ(JATL)に対してバグが報告されているので、私はこれを知っています。したがって、(copy n 'paste) クラス(JDOMから一部を盗んだもの)をドロップすることで、属性と要素コンテンツのエスケープを区別します

これまであまり重要ではなかったかもしれませんが(適切な属性のエスケープ)、HTML5のdata-属性の使用法を考えると、ますます関心が高まっています。

10
Adam Gent

org.Apache.commons.lang3.StringEscapeUtilsは現在推奨されていません。これでorg.Apache.commons.text.StringEscapeUtilsを使用する必要があります。

    <dependency>
        <groupId>org.Apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>${commons.text.version}</version>
    </dependency>
3