説明
Webアプリケーションがページ生成時に信頼できない入力を適切に扱わないと、ユーザーのブラウザーで悪意のあるスクリプトが実行されるXSSが起こる可能性があります。
想定される影響
- 悪意のあるスクリプトが個人データを盗んだり、アプリケーションの保護を回避したりするおそれがあります。
- ページの機密データやスクリプトから読めるCookieが漏えいする可能性があります。
HttpOnlyCookieだけでは、被害者の権限で行われる操作を防げません。 - 攻撃者がブラウザーのコンテキストで任意のコードを実行できるおそれがあります。
対処方法
- 出力時に、HTMLテキスト、属性、JavaScriptなど実際のコンテキストに合わせてエンコードしてください。HTMLテキストのエスケープはJavaScriptのエンコードやURL検証の代わりにはなりません。可能なら自動エスケープ付きテンプレートを使ってください。
- Content Security Policy(CSP)でスクリプト実行を制限し、防御を追加してください。
- Spring Securityを追加するだけでは、ユーザー入力は自動エンコードされません。HTML入力が必要なら、検証済みの許可リストポリシーで無害化してください。
例
Springコントローラーの応答がHTMLとして表示される場合を前提とします。HtmlUtilsはorg.springframework.web.util.HtmlUtilsであり、以下のエンコードはHTMLテキストの位置に適用します。
変更前
java
// 変更前
@RequestMapping("/welcome")
@ResponseBody
public String welcomeMessage(@RequestParam String username) {
// 入力をHTMLへ直接挿入
return "<h1>Welcome, " + username + "!</h1>";
}
変更後
java
// 変更後
@RequestMapping("/welcome")
@ResponseBody
public String welcomeMessage(@RequestParam String username) {
// 入力をHTMLテキストとしてエンコード
String safeUsername = HtmlUtils.htmlEscape(username);
return "<h1>Welcome, " + safeUsername + "!</h1>";
}
説明:
- 変更前:
usernameをHTMLへ直接挿入します。入力に悪意のあるスクリプトが含まれると、ブラウザーで実行されるおそれがあります。 - 変更後:
HtmlUtils.htmlEscapeで入力をHTMLテキストとしてエンコードします。この位置では、入力のマークアップは実行されずテキストとして表示されます。
関連CVE
- CVE-2021-25926: Python Library Manager did not sufficiently neutralize a user-supplied search term, allowing reflected XSS.
- CVE-2021-25963: Python-based e-commerce platform did not escape returned content on error pages, allowing for reflected Cross-Site Scripting attacks.
- CVE-2021-1879: Universal XSS in mobile operating system, as exploited in the wild per CISA KEV.