こちらは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 | < | < < |
< < |
< < |
true |
U+00D5 | Õ | Õ Õ |
Õ Õ |
Õ Õ |
true |
U+221A | √ | √ √ |
√ √ |
√ √ |
true |
U+00D6 | Ö | Ö Ö |
Ö Ö |
Ö Ö |
true |
U+221D | ∝ | ∝ ∝ |
∝ ∝ |
∝ ∝ |
true |
U+003E | > | > > |
> > |
> > |
true |
U+00D7 | × | × × |
× × |
× × |
true |
U+00D8 | Ø | Ø Ø |
Ø Ø |
Ø Ø |
true |
U+00D9 | Ù | Ù Ù |
Ù Ù |
Ù Ù |
true |
U+221E | ∞ | ∞ ∞ |
∞ ∞ |
∞ ∞ |
true |
U+0160 | Š | Š Š |
Š Š |
Š Š |
true |
U+0161 | š | š š |
š š |
š š |
true |
U+00DA | Ú | Ú Ú |
Ú Ú |
Ú Ú |
true |
U+00DB | Û | Û Û |
Û Û |
Û Û |
true |
U+00DC | Ü | Ü Ü |
Ü Ü |
Ü Ü |
true |
U+2220 | ∠ | ∠ ∠ |
∠ ∠ |
∠ ∠ |
true |
U+00DD | Ý | Ý Ý |
Ý Ý |
Ý Ý |
true |
U+00DE | Þ | Þ Þ |
Þ Þ |
Þ Þ |
true |
U+00DF | ß | ß ß |
ß ß |
ß ß |
true |
U+2227 | ∧ | ∧ ∧ |
∧ ∧ |
∧ ∧ |
true |
U+2229 | ∩ | ∩ ∩ |
∩ ∩ |
∩ ∩ |
true |
U+2228 | ∨ | ∨ ∨ |
∨ ∨ |
∨ ∨ |
true |
U+03C0 | π | π π |
π π |
π π |
true |
U+03C1 | ρ | ρ ρ |
ρ ρ |
ρ ρ |
true |
U+03C2 | ς | ς ς |
ς ς |
ς ς |
true |
U+03C3 | σ | σ σ |
σ σ |
σ σ |
true |
U+03C4 | τ | τ τ |
τ τ |
τ τ |
true |
U+03C5 | υ | υ υ |
υ υ |
υ υ |
true |
U+03C6 | φ | φ φ |
φ φ |
φ φ |
true |
U+2191 | ↑ | ↑ ↑ |
↑ ↑ |
↑ ↑ |
true |
U+03C7 | χ | χ χ |
χ χ |
χ χ |
true |
U+2190 | ← | ← ← |
← ← |
← ← |
true |
U+03C8 | ψ | ψ ψ |
ψ ψ |
ψ ψ |
true |
U+2193 | ↓ | ↓ ↓ |
↓ ↓ |
↓ ↓ |
true |
U+03C9 | ω | ω ω |
ω ω |
ω ω |
true |
U+2192 | → | → → |
→ → |
→ → |
true |
U+2194 | ↔ | ↔ ↔ |
↔ ↔ |
↔ ↔ |
true |
U+03D1 | ϑ | ϑ ϑ |
ϑ ϑ |
ϑ ϑ |
true |
U+03D2 | ϒ | ϒ ϒ |
ϒ ϒ |
ϒ ϒ |
true |
U+03D6 | ϖ | ϖ ϖ |
ϖ ϖ |
ϖ ϖ |
true |
U+02C6 | ˆ | ˆ ˆ |
ˆ ˆ |
ˆ ˆ |
true |
U+25CA | ◊ | ◊ ◊ |
◊ ◊ |
◊ ◊ |
true |
U+2660 | ♠ | ♠ ♠ |
♠ ♠ |
♠ ♠ |
true |
U+2663 | ♣ | ♣ ♣ |
♣ ♣ |
♣ ♣ |
true |
U+02DC | ˜ | ˜ ˜ |
˜ ˜ |
˜ ˜ |
true |
U+2665 | ♥ | ♥ ♥ |
♥ ♥ |
♥ ♥ |
true |
U+2666 | ♦ | ♦ ♦ |
♦ ♦ |
♦ ♦ |
true |
U+2308 | ⌈ | ⌈ ⌈ |
⌈ ⌈ |
⌈ ⌈ |
true |
U+2030 | ‰ | ‰ ‰ |
‰ ‰ |
‰ ‰ |
true |
U+2032 | ′ | ′ ′ |
′ ′ |
′ ′ |
true |
U+2033 | ″ | ″ ″ |
″ ″ |
″ ″ |
true |
U+2039 | ‹ | ‹ ‹ |
‹ ‹ |
‹ ‹ |
true |
U+203A | › | › › |
› › |
› › |
true |
U+203E | ‾ | ‾ ‾ |
‾ ‾ |
‾ ‾ |
true |
U+2283 | ⊃ | ⊃ ⊃ |
⊃ ⊃ |
⊃ ⊃ |
true |
U+2282 | ⊂ | ⊂ ⊂ |
⊂ ⊂ |
⊂ ⊂ |
true |
U+2284 | ⊄ | ⊄ ⊄ |
⊄ ⊄ |
⊄ ⊄ |
true |
U+2287 | ⊇ | ⊇ ⊇ |
⊇ ⊇ |
⊇ ⊇ |
true |
U+2044 | ⁄ | ⁄ ⁄ |
⁄ ⁄ |
⁄ ⁄ |
true |
U+2286 | ⊆ | ⊆ ⊆ |
⊆ ⊆ |
⊆ ⊆ |
true |
U+03A0 | Π | Π Π |
Π Π |
Π Π |
true |
U+03A1 | Ρ | Ρ Ρ |
Ρ Ρ |
Ρ Ρ |
true |
U+03A3 | Σ | Σ Σ |
Σ Σ |
Σ Σ |
true |
U+03A4 | Τ | Τ Τ |
Τ Τ |
Τ Τ |
true |
U+03A5 | Υ | Υ Υ |
Υ Υ |
Υ Υ |
true |
U+03A6 | Φ | Φ Φ |
Φ Φ |
Φ Φ |
true |
U+03A7 | Χ | Χ Χ |
Χ Χ |
Χ Χ |
true |
U+03A8 | Ψ | Ψ Ψ |
Ψ Ψ |
Ψ Ψ |
true |
U+03A9 | Ω | Ω Ω |
Ω Ω |
Ω Ω |
true |
U+2295 | ⊕ | ⊕ ⊕ |
⊕ ⊕ |
⊕ ⊕ |
true |
U+2297 | ⊗ | ⊗ ⊗ |
⊗ ⊗ |
⊗ ⊗ |
true |
U+03B1 | α | α α |
α α |
α α |
true |
U+03B2 | β | β β |
β β |
β β |
true |
U+03B3 | γ | γ γ |
γ γ |
γ γ |
true |
U+03B4 | δ | δ δ |
δ δ |
δ δ |
true |
U+03B5 | ε | ε ε |
ε ε |
ε ε |
true |
U+03B6 | ζ | ζ ζ |
ζ ζ |
ζ ζ |
true |
U+03B7 | η | η η |
η η |
η η |
true |
U+03B8 | θ | θ θ |
θ θ |
θ θ |
true |
U+03B9 | ι | ι ι |
ι ι |
ι ι |
true |
U+03BA | κ | κ κ |
κ κ |
κ κ |
true |
U+03BB | λ | λ λ |
λ λ |
λ λ |
true |
U+03BC | μ | μ μ |
μ μ |
μ μ |
true |
U+03BD | ν | ν ν |
ν ν |
ν ν |
true |
U+03BE | ξ | ξ ξ |
ξ ξ |
ξ ξ |
true |
U+03BF | ο | ο ο |
ο ο |
ο ο |
true |
U+00E0 | à | à à |
à à |
à à |
true |
U+00E1 | á | á á |
á á |
á á |
true |
U+00E2 | â | â â |
â â |
â â |
true |
U+00E3 | ã | ã ã |
ã ã |
ã ã |
true |
U+222A | ∪ | ∪ ∪ |
∪ ∪ |
∪ ∪ |
true |
U+00E4 | ä | ä ä |
ä ä |
ä ä |
true |
U+00E5 | å | å å |
å å |
å å |
true |
U+00E6 | æ | æ æ |
æ æ |
æ æ |
true |
U+222B | ∫ | ∫ ∫ |
∫ ∫ |
∫ ∫ |
true |
U+00E7 | ç | ç ç |
ç ç |
ç ç |
true |
U+00E8 | è | è è |
è è |
è è |
true |
U+22C5 | ⋅ | ⋅ ⋅ |
⋅ ⋅ |
⋅ ⋅ |
true |
U+00E9 | é | é é |
é é |
é é |
true |
U+00EA | ê | ê ê |
ê ê |
ê ê |
true |
U+00EB | ë | ë ë |
ë ë |
ë ë |
true |
U+00EC | ì | ì ì |
ì ì |
ì ì |
true |
U+2111 | ℑ | ℑ ℑ |
ℑ ℑ |
ℑ ℑ |
true |
U+00ED | í | í í |
í í |
í í |
true |
U+00EE | î | î î |
î î |
î î |
true |
U+2234 | ∴ | ∴ ∴ |
∴ ∴ |
∴ ∴ |
true |
U+00EF | ï | ï ï |
ï ï |
ï ï |
true |
U+0178 | Ÿ | Ÿ Ÿ |
Ÿ Ÿ |
Ÿ Ÿ |
true |
U+2118 | ℘ | ℘ ℘ |
℘ ℘ |
℘ ℘ |
true |
U+00F0 | ð | ð ð |
ð ð |
ð ð |
true |
U+00F1 | ñ | ñ ñ |
ñ ñ |
ñ ñ |
true |
U+00F2 | ò | ò ò |
ò ò |
ò ò |
true |
U+00F3 | ó | ó ó |
ó ó |
ó ó |
true |
U+00F4 | ô | ô ô |
ô ô |
ô ô |
true |
U+00F5 | õ | õ õ |
õ õ |
õ õ |
true |
U+00F6 | ö | ö ö |
ö ö |
ö ö |
true |
U+211C | ℜ | ℜ ℜ |
ℜ ℜ |
ℜ ℜ |
true |
U+00F7 | ÷ | ÷ ÷ |
÷ ÷ |
÷ ÷ |
true |
U+223C | ∼ | ∼ ∼ |
∼ ∼ |
∼ ∼ |
true |
U+00F8 | ø | ø ø |
ø ø |
ø ø |
true |
U+00F9 | ù | ù ù |
ù ù |
ù ù |
true |
U+21B5 | ↵ | ↵ ↵ |
↵ ↵ |
↵ ↵ |
true |
U+00FA | ú | ú ú |
ú ú |
ú ú |
true |
U+00FB | û | û û |
û û |
û û |
true |
U+00FC | ü | ü ü |
ü ü |
ü ü |
true |
U+00FD | ý | ý ý |
ý ý |
ý ý |
true |
U+2122 | ™ | ™ ™ |
™ ™ |
™ ™ |
true |
U+00FE | þ | þ þ |
þ þ |
þ þ |
true |
U+00FF | ÿ | ÿ ÿ |
ÿ ÿ |
ÿ ÿ |
true |
U+2245 | ≅ | ≅ ≅ |
≅ ≅ |
≅ ≅ |
true |
U+2003 |   |
  |
  |
true | |
U+2002 |   |
  |
  |
true | |
U+2248 | ≈ | ≈ ≈ |
≈ ≈ |
≈ ≈ |
true |
U+2009 |   |
  |
  |
true | |
U+200C | | ‌ |
‌ |
‌ |
true |
U+200E | | ‎ |
‎ |
‎ |
true |
U+200D | | ‍ |
‍ |
‍ |
true |
U+200F | | ‏ |
‏ |
‏ |
true |
U+0192 | ƒ | ƒ ƒ |
ƒ ƒ |
ƒ ƒ |
true |
U+2135 | ℵ | ℵ ℵ |
ℵ ℵ |
ℵ ℵ |
true |
U+2014 | — | — — |
— — |
— — |
true |
U+2013 | – | – – |
– – |
– – |
true |
U+20AC | € | € € |
€ € |
€ € |
true |
U+2018 | ‘ | ‘ ‘ |
‘ ‘ |
‘ ‘ |
true |
U+2019 | ’ | ’ ’ |
’ ’ |
’ ’ |
true |
U+21D0 | ⇐ | ⇐ ⇐ |
⇐ ⇐ |
⇐ ⇐ |
true |
U+21D2 | ⇒ | ⇒ ⇒ |
⇒ ⇒ |
⇒ ⇒ |
true |
U+21D1 | ⇑ | ⇑ ⇑ |
⇑ ⇑ |
⇑ ⇑ |
true |
U+21D4 | ⇔ | ⇔ ⇔ |
⇔ ⇔ |
⇔ ⇔ |
true |
U+21D3 | ⇓ | ⇓ ⇓ |
⇓ ⇓ |
⇓ ⇓ |
true |
U+201A | ‚ | ‚ ‚ |
‚ ‚ |
‚ ‚ |
true |
U+201D | ” | ” ” |
” ” |
” ” |
true |
U+201C | “ | “ “ |
“ “ |
“ “ |
true |
U+201E | „ | „ „ |
„ „ |
„ „ |
true |
U+2261 | ≡ | ≡ ≡ |
≡ ≡ |
≡ ≡ |
true |
U+2260 | ≠ | ≠ ≠ |
≠ ≠ |
≠ ≠ |
true |
U+2021 | ‡ | ‡ ‡ |
‡ ‡ |
‡ ‡ |
true |
U+2020 | † | † † |
† † |
† † |
true |
U+2265 | ≥ | ≥ ≥ |
≥ ≥ |
≥ ≥ |
true |
U+2022 | • | • • |
• • |
• • |
true |
U+2264 | ≤ | ≤ ≤ |
≤ ≤ |
≤ ≤ |
true |
U+2026 | … | … … |
… … |
… … |
true |
考察
おしい、1点だけ結果に差異を発見しました。
『Æ』(U+00C6)
文字実体参照か数値文字参照かの違いなので結果としての見え方に差異はないです。
これは、なんか処理が不足してたりしないかunbescapeのソースコード見てみたいところです。
さいごに
XSS対策のサニタイジング用として使われているエスケープ処理ですが
実は、他にもいろいろエスケープしていた事を知ることが出来ました。
普段何気なく使っている関数に、実は思わぬ実装がされているかもしれませんので、
ふっと結果を調べてみたりソースを覗いてみると、新たな発見があるかもしれません。
おまけ宣伝
今回、セキュリティの話を書きましたが、セキュリティのLT会を2025年1月23日に企画しています。
ご興味があれば是非、遊びに来てくださいw
Security.any #02 セキュリティあの頃はLT