3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaAdvent Calendar 2024

Day 16

XSS対策としてのHTML4エスケープに踏み込んで有名ライブラリの処理を比較してみた

Last updated at Posted at 2024-12-16

こちらはJava Advent Calendar 2024の16日目の記事となります。

HTMLエスケープ

フロントエンドのWebシステムを開発していれば、
XSS(クロスサイトスクリプティング)という脆弱性は耳にしたことある人が大多数ではないかと思っています。
※その点は今回は掘り下げないので、有名な本や記事などで学んでください。

今回はそのXSS対策として行われる各ライブラリが実装しているHTMLエスケープについて注目してみました。
サニタイジング(無害化)の観点では、『&』等のHTML構成要素を実体参照『& -> &』に置き換える事で
HTMLとして機能させなくする意味合いと理解していますが、HTMLエスケープはもう少し広義な意味となっています。
※この点も今回は掘り下げませんので、有名な本や記事などで学んでください。

有名ライブラリを比較してみた

HTMLエスケープの実装はそれぞれバラバラだったので、実際に差異があるかどうかを出力して調べてみました。
比較に使用した文字はHTML4における文字実体参照から全文字をリストアップしてみました。

比較ライブラリ

ライブラリ名 エスケープ関数
Spring Framework HtmlUtils#htmlEscape
Commons Text StringEscapeUtils#escapeHtml4
unbescape(Thymeleafにて利用) HtmlEscape#.escapeHtml4

比較結果

※各ライブラリの結果(3-5列目)の1行目は参照文字を表示、2行目はその文字列を表示

Unicode エスケープ前 Spring Framework Commons Text unbescape 差異有無
U+2309
⌉

⌉

⌉
true
U+00A0    
 
 
 
 
 
true
U+00A1 ¡ ¡
¡
¡
¡
¡
¡
true
U+00A2 ¢ ¢
¢
¢
¢
¢
¢
true
U+00A3 £ £
£
£
£
£
£
true
U+230B
⌋

⌋

⌋
true
U+00A4 ¤ ¤
¤
¤
¤
¤
¤
true
U+230A
⌊

⌊

⌊
true
U+00A5 ¥ ¥
¥
¥
¥
¥
¥
true
U+00A6 ¦ ¦
¦
¦
¦
¦
¦
true
U+00A7 § §
§
§
§
§
§
true
U+00A8 ¨ ¨
¨
¨
¨
¨
¨
true
U+00A9 © ©
©
©
©
©
©
true
U+00AA ª ª
ª
ª
ª
ª
ª
true
U+00AB « «
«
«
«
«
«
true
U+00AC ¬ ¬
¬
¬
¬
¬
¬
true
U+00AD ­ ­
­
­
­
­
­
true
U+00AE ® ®
®
®
®
®
®
true
U+00AF ¯ ¯
¯
¯
¯
¯
¯
true
U+00B0 ° °
°
°
°
°
°
true
U+00B1 ± ±
±
±
±
±
±
true
U+00B2 ² ²
²
²
²
²
²
true
U+00B3 ³ ³
³
³
³
³
³
true
U+00B4 ´ ´
´
´
´
´
´
true
U+00B5 µ µ
µ
µ
µ
µ
µ
true
U+00B6
¶

¶

¶
true
U+00B7 · ·
·
·
·
·
·
true
U+00B8 ¸ ¸
¸
¸
¸
¸
¸
true
U+00B9 ¹ ¹
¹
¹
¹
¹
¹
true
U+00BA º º
º
º
º
º
º
true
U+00BB » »
»
»
»
»
»
true
U+0022 " "
"
"
"
"
"
true
U+00BC ¼ ¼
¼
¼
¼
¼
¼
true
U+2200
∀

∀

∀
true
U+00BD ½ ½
½
½
½
½
½
true
U+2203
∃

∃

∃
true
U+00BE ¾ ¾
¾
¾
¾
¾
¾
true
U+2202
∂

∂

∂
true
U+00BF ¿ ¿
¿
¿
¿
¿
¿
true
U+2205
∅

∅

∅
true
U+0026 & &
&
&
&
&
&
true
U+2207
∇

∇

∇
true
U+2209
∉

∉

∉
true
U+2208
∈

∈

∈
true
U+2329
⟨

⟨

⟨
true
U+00C0 À À
À
À
À
À
À
true
U+00C1 Á Á
Á
Á
Á
Á
Á
true
U+00C2 Â Â
Â
Â
Â
Â
Â
true
U+00C3 Ã Ã
Ã
Ã
Ã
Ã
Ã
true
U+00C4 Ä Ä
Ä
Ä
Ä
Ä
Ä
true
U+232A
⟩

⟩

⟩
true
U+00C5 Å Å
Å
Å
Å
Å
Å
true
U+00C6 Æ Æ
Æ
Æ
Æ
Æ
Æ
false
U+220B
∋

∋

∋
true
U+00C7 Ç Ç
Ç
Ç
Ç
Ç
Ç
true
U+00C8 È È
È
È
È
È
È
true
U+22A5
⊥

⊥

⊥
true
U+00C9 É É
É
É
É
É
É
true
U+220F
∏

∏

∏
true
U+0391 Α Α
Α
Α
Α
Α
Α
true
U+0392 Β Β
Β
Β
Β
Β
Β
true
U+0393 Γ Γ
Γ
Γ
Γ
Γ
Γ
true
U+00CA Ê Ê
Ê
Ê
Ê
Ê
Ê
true
U+0394 Δ Δ
Δ
Δ
Δ
Δ
Δ
true
U+0152 Œ Œ
Œ
Œ
Œ
Œ
Œ
true
U+00CB Ë Ë
Ë
Ë
Ë
Ë
Ë
true
U+0395 Ε Ε
Ε
Ε
Ε
Ε
Ε
true
U+0153 œ œ
œ
œ
œ
œ
œ
true
U+00CC Ì Ì
Ì
Ì
Ì
Ì
Ì
true
U+0396 Ζ Ζ
Ζ
Ζ
Ζ
Ζ
Ζ
true
U+2212
−

−

−
true
U+00CD Í Í
Í
Í
Í
Í
Í
true
U+0397 Η Η
Η
Η
Η
Η
Η
true
U+2211
∑

∑

∑
true
U+00CE Î Î
Î
Î
Î
Î
Î
true
U+0398 Θ Θ
Θ
Θ
Θ
Θ
Θ
true
U+00CF Ï Ï
Ï
Ï
Ï
Ï
Ï
true
U+0399 Ι Ι
Ι
Ι
Ι
Ι
Ι
true
U+2217
∗

∗

∗
true
U+039A Κ Κ
Κ
Κ
Κ
Κ
Κ
true
U+00D0 Ð Ð
Ð
Ð
Ð
Ð
Ð
true
U+039B Λ Λ
Λ
Λ
Λ
Λ
Λ
true
U+00D1 Ñ Ñ
Ñ
Ñ
Ñ
Ñ
Ñ
true
U+039C Μ Μ
Μ
Μ
Μ
Μ
Μ
true
U+00D2 Ò Ò
Ò
Ò
Ò
Ò
Ò
true
U+039D Ν Ν
Ν
Ν
Ν
Ν
Ν
true
U+00D3 Ó Ó
Ó
Ó
Ó
Ó
Ó
true
U+039E Ξ Ξ
Ξ
Ξ
Ξ
Ξ
Ξ
true
U+00D4 Ô Ô
Ô
Ô
Ô
Ô
Ô
true
U+039F Ο Ο
Ο
Ο
Ο
Ο
Ο
true
U+003C < <
&lt;
<
&lt;
<
&lt;
true
U+00D5 Õ Õ
&Otilde;
Õ
&Otilde;
Õ
&Otilde;
true
U+221A
&radic;

&radic;

&radic;
true
U+00D6 Ö Ö
&Ouml;
Ö
&Ouml;
Ö
&Ouml;
true
U+221D
&prop;

&prop;

&prop;
true
U+003E > >
&gt;
>
&gt;
>
&gt;
true
U+00D7 × ×
&times;
×
&times;
×
&times;
true
U+00D8 Ø Ø
&Oslash;
Ø
&Oslash;
Ø
&Oslash;
true
U+00D9 Ù Ù
&Ugrave;
Ù
&Ugrave;
Ù
&Ugrave;
true
U+221E
&infin;

&infin;

&infin;
true
U+0160 Š Š
&Scaron;
Š
&Scaron;
Š
&Scaron;
true
U+0161 š š
&scaron;
š
&scaron;
š
&scaron;
true
U+00DA Ú Ú
&Uacute;
Ú
&Uacute;
Ú
&Uacute;
true
U+00DB Û Û
&Ucirc;
Û
&Ucirc;
Û
&Ucirc;
true
U+00DC Ü Ü
&Uuml;
Ü
&Uuml;
Ü
&Uuml;
true
U+2220
&ang;

&ang;

&ang;
true
U+00DD Ý Ý
&Yacute;
Ý
&Yacute;
Ý
&Yacute;
true
U+00DE Þ Þ
&THORN;
Þ
&THORN;
Þ
&THORN;
true
U+00DF ß ß
&szlig;
ß
&szlig;
ß
&szlig;
true
U+2227
&and;

&and;

&and;
true
U+2229
&cap;

&cap;

&cap;
true
U+2228
&or;

&or;

&or;
true
U+03C0 π π
&pi;
π
&pi;
π
&pi;
true
U+03C1 ρ ρ
&rho;
ρ
&rho;
ρ
&rho;
true
U+03C2 ς ς
&sigmaf;
ς
&sigmaf;
ς
&sigmaf;
true
U+03C3 σ σ
&sigma;
σ
&sigma;
σ
&sigma;
true
U+03C4 τ τ
&tau;
τ
&tau;
τ
&tau;
true
U+03C5 υ υ
&upsilon;
υ
&upsilon;
υ
&upsilon;
true
U+03C6 φ φ
&phi;
φ
&phi;
φ
&phi;
true
U+2191
&uarr;

&uarr;

&uarr;
true
U+03C7 χ χ
&chi;
χ
&chi;
χ
&chi;
true
U+2190
&larr;

&larr;

&larr;
true
U+03C8 ψ ψ
&psi;
ψ
&psi;
ψ
&psi;
true
U+2193
&darr;

&darr;

&darr;
true
U+03C9 ω ω
&omega;
ω
&omega;
ω
&omega;
true
U+2192
&rarr;

&rarr;

&rarr;
true
U+2194
&harr;

&harr;

&harr;
true
U+03D1 ϑ ϑ
&thetasym;
ϑ
&thetasym;
ϑ
&thetasym;
true
U+03D2 ϒ ϒ
&upsih;
ϒ
&upsih;
ϒ
&upsih;
true
U+03D6 ϖ ϖ
&piv;
ϖ
&piv;
ϖ
&piv;
true
U+02C6 ˆ ˆ
&circ;
ˆ
&circ;
ˆ
&circ;
true
U+25CA
&loz;

&loz;

&loz;
true
U+2660
&spades;

&spades;

&spades;
true
U+2663
&clubs;

&clubs;

&clubs;
true
U+02DC ˜ ˜
&tilde;
˜
&tilde;
˜
&tilde;
true
U+2665
&hearts;

&hearts;

&hearts;
true
U+2666
&diams;

&diams;

&diams;
true
U+2308
&lceil;

&lceil;

&lceil;
true
U+2030
&permil;

&permil;

&permil;
true
U+2032
&prime;

&prime;

&prime;
true
U+2033
&Prime;

&Prime;

&Prime;
true
U+2039
&lsaquo;

&lsaquo;

&lsaquo;
true
U+203A
&rsaquo;

&rsaquo;

&rsaquo;
true
U+203E
&oline;

&oline;

&oline;
true
U+2283
&sup;

&sup;

&sup;
true
U+2282
&sub;

&sub;

&sub;
true
U+2284
&nsub;

&nsub;

&nsub;
true
U+2287
&supe;

&supe;

&supe;
true
U+2044
&frasl;

&frasl;

&frasl;
true
U+2286
&sube;

&sube;

&sube;
true
U+03A0 Π Π
&Pi;
Π
&Pi;
Π
&Pi;
true
U+03A1 Ρ Ρ
&Rho;
Ρ
&Rho;
Ρ
&Rho;
true
U+03A3 Σ Σ
&Sigma;
Σ
&Sigma;
Σ
&Sigma;
true
U+03A4 Τ Τ
&Tau;
Τ
&Tau;
Τ
&Tau;
true
U+03A5 Υ Υ
&Upsilon;
Υ
&Upsilon;
Υ
&Upsilon;
true
U+03A6 Φ Φ
&Phi;
Φ
&Phi;
Φ
&Phi;
true
U+03A7 Χ Χ
&Chi;
Χ
&Chi;
Χ
&Chi;
true
U+03A8 Ψ Ψ
&Psi;
Ψ
&Psi;
Ψ
&Psi;
true
U+03A9 Ω Ω
&Omega;
Ω
&Omega;
Ω
&Omega;
true
U+2295
&oplus;

&oplus;

&oplus;
true
U+2297
&otimes;

&otimes;

&otimes;
true
U+03B1 α α
&alpha;
α
&alpha;
α
&alpha;
true
U+03B2 β β
&beta;
β
&beta;
β
&beta;
true
U+03B3 γ γ
&gamma;
γ
&gamma;
γ
&gamma;
true
U+03B4 δ δ
&delta;
δ
&delta;
δ
&delta;
true
U+03B5 ε ε
&epsilon;
ε
&epsilon;
ε
&epsilon;
true
U+03B6 ζ ζ
&zeta;
ζ
&zeta;
ζ
&zeta;
true
U+03B7 η η
&eta;
η
&eta;
η
&eta;
true
U+03B8 θ θ
&theta;
θ
&theta;
θ
&theta;
true
U+03B9 ι ι
&iota;
ι
&iota;
ι
&iota;
true
U+03BA κ κ
&kappa;
κ
&kappa;
κ
&kappa;
true
U+03BB λ λ
&lambda;
λ
&lambda;
λ
&lambda;
true
U+03BC μ μ
&mu;
μ
&mu;
μ
&mu;
true
U+03BD ν ν
&nu;
ν
&nu;
ν
&nu;
true
U+03BE ξ ξ
&xi;
ξ
&xi;
ξ
&xi;
true
U+03BF ο ο
&omicron;
ο
&omicron;
ο
&omicron;
true
U+00E0 à à
&agrave;
à
&agrave;
à
&agrave;
true
U+00E1 á á
&aacute;
á
&aacute;
á
&aacute;
true
U+00E2 â â
&acirc;
â
&acirc;
â
&acirc;
true
U+00E3 ã ã
&atilde;
ã
&atilde;
ã
&atilde;
true
U+222A
&cup;

&cup;

&cup;
true
U+00E4 ä ä
&auml;
ä
&auml;
ä
&auml;
true
U+00E5 å å
&aring;
å
&aring;
å
&aring;
true
U+00E6 æ æ
&aelig;
æ
&aelig;
æ
&aelig;
true
U+222B
&int;

&int;

&int;
true
U+00E7 ç ç
&ccedil;
ç
&ccedil;
ç
&ccedil;
true
U+00E8 è è
&egrave;
è
&egrave;
è
&egrave;
true
U+22C5
&sdot;

&sdot;

&sdot;
true
U+00E9 é é
&eacute;
é
&eacute;
é
&eacute;
true
U+00EA ê ê
&ecirc;
ê
&ecirc;
ê
&ecirc;
true
U+00EB ë ë
&euml;
ë
&euml;
ë
&euml;
true
U+00EC ì ì
&igrave;
ì
&igrave;
ì
&igrave;
true
U+2111
&image;

&image;

&image;
true
U+00ED í í
&iacute;
í
&iacute;
í
&iacute;
true
U+00EE î î
&icirc;
î
&icirc;
î
&icirc;
true
U+2234
&there4;

&there4;

&there4;
true
U+00EF ï ï
&iuml;
ï
&iuml;
ï
&iuml;
true
U+0178 Ÿ Ÿ
&Yuml;
Ÿ
&Yuml;
Ÿ
&Yuml;
true
U+2118
&weierp;

&weierp;

&weierp;
true
U+00F0 ð ð
&eth;
ð
&eth;
ð
&eth;
true
U+00F1 ñ ñ
&ntilde;
ñ
&ntilde;
ñ
&ntilde;
true
U+00F2 ò ò
&ograve;
ò
&ograve;
ò
&ograve;
true
U+00F3 ó ó
&oacute;
ó
&oacute;
ó
&oacute;
true
U+00F4 ô ô
&ocirc;
ô
&ocirc;
ô
&ocirc;
true
U+00F5 õ õ
&otilde;
õ
&otilde;
õ
&otilde;
true
U+00F6 ö ö
&ouml;
ö
&ouml;
ö
&ouml;
true
U+211C
&real;

&real;

&real;
true
U+00F7 ÷ ÷
&divide;
÷
&divide;
÷
&divide;
true
U+223C
&sim;

&sim;

&sim;
true
U+00F8 ø ø
&oslash;
ø
&oslash;
ø
&oslash;
true
U+00F9 ù ù
&ugrave;
ù
&ugrave;
ù
&ugrave;
true
U+21B5
&crarr;

&crarr;

&crarr;
true
U+00FA ú ú
&uacute;
ú
&uacute;
ú
&uacute;
true
U+00FB û û
&ucirc;
û
&ucirc;
û
&ucirc;
true
U+00FC ü ü
&uuml;
ü
&uuml;
ü
&uuml;
true
U+00FD ý ý
&yacute;
ý
&yacute;
ý
&yacute;
true
U+2122
&trade;

&trade;

&trade;
true
U+00FE þ þ
&thorn;
þ
&thorn;
þ
&thorn;
true
U+00FF ÿ ÿ
&yuml;
ÿ
&yuml;
ÿ
&yuml;
true
U+2245
&cong;

&cong;

&cong;
true
U+2003
&emsp;

&emsp;

&emsp;
true
U+2002
&ensp;

&ensp;

&ensp;
true
U+2248
&asymp;

&asymp;

&asymp;
true
U+2009
&thinsp;

&thinsp;

&thinsp;
true
U+200C
&zwnj;

&zwnj;

&zwnj;
true
U+200E
&lrm;

&lrm;

&lrm;
true
U+200D
&zwj;

&zwj;

&zwj;
true
U+200F
&rlm;

&rlm;

&rlm;
true
U+0192 ƒ ƒ
&fnof;
ƒ
&fnof;
ƒ
&fnof;
true
U+2135
&alefsym;

&alefsym;

&alefsym;
true
U+2014
&mdash;

&mdash;

&mdash;
true
U+2013
&ndash;

&ndash;

&ndash;
true
U+20AC
&euro;

&euro;

&euro;
true
U+2018
&lsquo;

&lsquo;

&lsquo;
true
U+2019
&rsquo;

&rsquo;

&rsquo;
true
U+21D0
&lArr;

&lArr;

&lArr;
true
U+21D2
&rArr;

&rArr;

&rArr;
true
U+21D1
&uArr;

&uArr;

&uArr;
true
U+21D4
&hArr;

&hArr;

&hArr;
true
U+21D3
&dArr;

&dArr;

&dArr;
true
U+201A
&sbquo;

&sbquo;

&sbquo;
true
U+201D
&rdquo;

&rdquo;

&rdquo;
true
U+201C
&ldquo;

&ldquo;

&ldquo;
true
U+201E
&bdquo;

&bdquo;

&bdquo;
true
U+2261
&equiv;

&equiv;

&equiv;
true
U+2260
&ne;

&ne;

&ne;
true
U+2021
&Dagger;

&Dagger;

&Dagger;
true
U+2020
&dagger;

&dagger;

&dagger;
true
U+2265
&ge;

&ge;

&ge;
true
U+2022
&bull;

&bull;

&bull;
true
U+2264
&le;

&le;

&le;
true
U+2026
&hellip;

&hellip;

&hellip;
true

考察

おしい、1点だけ結果に差異を発見しました。

『Æ』(U+00C6)

文字実体参照か数値文字参照かの違いなので結果としての見え方に差異はないです。
これは、なんか処理が不足してたりしないかunbescapeのソースコード見てみたいところです。

さいごに

XSS対策のサニタイジング用として使われているエスケープ処理ですが
実は、他にもいろいろエスケープしていた事を知ることが出来ました。

普段何気なく使っている関数に、実は思わぬ実装がされているかもしれませんので、
ふっと結果を調べてみたりソースを覗いてみると、新たな発見があるかもしれません。

おまけ宣伝

今回、セキュリティの話を書きましたが、セキュリティのLT会を2025年1月23日に企画しています。
ご興味があれば是非、遊びに来てくださいw
Security.any #02 セキュリティあの頃はLT

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?