XSS(クロスサイトスクリプティング)攻撃について
XSS(Cross-Site Scripting)は、Webアプリケーションの脆弱性を利用して、攻撃者がユーザーのブラウザ上で悪意のあるスクリプトを実行させる攻撃手法です。これにより、ユーザーのセッションを乗っ取ったり、クッキーを盗んだり、フィッシング詐欺を仕掛けたりすることができます。XSSは、特にユーザー入力を適切に処理しないWebアプリケーションにおいて発生しやすく、攻撃者は様々な方法でXSSを仕掛けることができます。主に、次の3つの種類に分類されます。
脆弱なコード例(Reflected XSS):
<?php
$name = $_GET['name'];
echo "Hello, " . $name . "!";
?>
攻撃手法: 攻撃者は、以下のようなURLを犠牲者にクリックさせることで、XSS攻撃を実行できます。
http://example.com/?name=<script>alert('XSS')</script>
この場合、スクリプトがページ内に埋め込まれてブラウザで実行され、アラートが表示されます。
脆弱なコード例(Stored XSS):
from flask import Flask, request, render_template_string
app = Flask(__name__)
comments = []
@app.route('/comment', methods=['POST'])
def comment():
comment = request.form['comment']
comments.append(comment)
return "Comment added!"
@app.route('/comments')
def view_comments():
return render_template_string("<ul></ul>", comments=comments)
if __name__ == '__main__':
app.run()
攻撃手法: 攻撃者が以下のようなコメントを投稿すると、他のユーザーがページを閲覧する際にXSS攻撃が実行されます。
<script>alert('XSS')</script>
脆弱なコード例(Reflected XSS):
const express = require('express');
const app = express();
app.get('/greet', (req, res) => {
const name = req.query.name;
res.send(`Hello, ${name}!`);
});
app.listen(3000);
攻撃手法: 攻撃者は、以下のようなURLを使用してXSS攻撃を実行できます。
http://localhost:3000/greet?name=<script>alert('XSS')</script>
脆弱なコード例(Reflected XSS):
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.stereotype.Controller;
@Controller
public class GreetingController {
@GetMapping("/greet")
public String greet(@RequestParam String name, Model model) {
model.addAttribute("message", "Hello, " + name + "!");
return "greet";
}
}
攻撃手法: 攻撃者は、以下のようなURLを使用してXSS攻撃を実行できます。
http://localhost:8080/greet?name=<script>alert('XSS')</script>
PHPの例:
echo "Hello, " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "!";
Pythonの例(Flask): Flaskのテンプレートエンジン(Jinja2)はデフォルトでエスケープ処理が行われますが、テンプレートの使用時には慎重に扱うべきです。
Node.jsの例:
const escapeHtml = require('escape-html');
res.send(`Hello, ${escapeHtml(name)}!`);
Javaの例(Spring): ThymeleafやJSPのテンプレートエンジンでは、デフォルトでエスケープ処理が行われます。
PHPの例:
$name = strip_tags($_GET['name']);
Pythonの例(Flask):
from bleach import clean
comment = clean(request.form['comment'])
PHPの例:
header("Content-Security-Policy: default-src 'self'");
Node.jsの例:
app.use((req, res, next) => {
res.setHeader("Content-Security-Policy", "default-src 'self'");
next();
});
HttpOnly
属性を設定し、JavaScriptからのアクセスを防ぎます。また、Secure
属性を設定して、HTTPS経由でのみクッキーが送信されるようにします。まとめ: XSS攻撃は、Webアプリケーションが適切なエスケープ処理やサニタイズを行わない場合に発生する脆弱性です。出力時のエスケープ、入力のサニタイズ、CSPの設定、セキュリティライブラリの使用などの防止策を実施することで、この脆弱性を効果的に防ぐことができます。各プラットフォームや言語に共通する問題であるため、これらの対策を適用することが推奨されます。
脆弱なコード例(Reflected XSS):
from flask import Flask, request
app = Flask(__name__)
@app.route('/greet')
def greet():
name = request.args.get('name')
return f"Hello, {name}!"
if __name__ == '__main__':
app.run()
攻撃手法: 攻撃者が以下のようなURLを使用してXSS攻撃を実行できます。
http://localhost:5000/greet?name=<script>alert('XSS')</script>
このURLをクリックすると、ブラウザ上でスクリプトが実行され、アラートが表示されます。
出力時のエスケープ処理:
修正されたコード例:
from flask import Flask, request
from markupsafe import escape
app = Flask(__name__)
@app.route('/greet')
def greet():
name = request.args.get('name')
safe_name = escape(name) # 入力をエスケープ
return f"Hello, {safe_name}!"
if __name__ == '__main__':
app.run()
escape
関数は、ユーザーの入力をHTMLで安全に表示できるようにエスケープ処理を行います。これにより、<script>
タグなどの特殊文字がそのまま表示され、スクリプトとして実行されることを防ぎます。
この対策により、攻撃者が<script>
タグを使用しても、それが文字列として扱われ、スクリプトが実行されることはなくなります。