キャッシュデセプション(Web Cache Deception)攻撃について
キャッシュデセプション(Web Cache Deception)攻撃は、Webサーバーやプロキシサーバーが動的コンテンツを誤ってキャッシュするように仕向ける攻撃手法です。攻撃者は、特定のリクエストパスを工夫することで、サーバーが本来キャッシュすべきでないユーザー固有の情報をキャッシュするように誘導します。その結果、他のユーザーがこのキャッシュされたコンテンツを取得することになり、機密情報が漏洩するリスクが生じます。
この攻撃は、サーバーが誤って動的コンテンツをキャッシュする場合に発生します。
攻撃者は、通常キャッシュされない動的コンテンツをキャッシュさせるために、リクエストURLの末尾に.jpg
、.css
、.js
などの静的リソース拡張子を付け加えます。これにより、サーバーやプロキシがこのリクエストを静的なリソースとして認識し、キャッシュするように誘導します。
例:
https://example.com/account/settings
https://example.com/account/settings/profile.jpg
サーバーが/account/settings/profile.jpg
を静的ファイルとして誤認すると、このリクエストがキャッシュされ、他のユーザーがアクセスした際に同じ内容が提供されます。
脆弱なコード例:
<?php
session_start();
if (!isset($_SESSION['user'])) {
header("Location: /login.php");
exit();
}
// ユーザー固有のデータを表示
echo "Welcome " . $_SESSION['user'];
?>
サーバー設定の例:
mod_cache
が有効で、特定の拡張子を持つリクエストがキャッシュされる設定になっている。攻撃手法:
攻撃者はhttps://example.com/account/settings/profile.jpg
のようなURLでリクエストを送信し、mod_cache
がこのページをキャッシュすると、他のユーザーがアクセスした際に攻撃者のセッション情報が表示される可能性があります。
脆弱なコード例:
from flask import Flask, session, redirect
app = Flask(__name__)
app.secret_key = 'super_secret_key'
@app.route('/account/settings')
def account_settings():
if 'user' not in session:
return redirect('/login')
return f"Welcome {session['user']}"
if __name__ == '__main__':
app.run()
サーバー設定の例:
攻撃手法:
攻撃者はhttps://example.com/account/settings/profile.js
のようなリクエストを送信し、Nginxがこのリクエストをキャッシュすると、他のユーザーが同じURLにアクセスしたときに攻撃者のセッションデータが表示される可能性があります。
脆弱なコード例:
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({ secret: 'super_secret_key', resave: false, saveUninitialized: true }));
app.get('/account/settings', (req, res) => {
if (!req.session.user) {
res.redirect('/login');
} else {
res.send(`Welcome ${req.session.user}`);
}
});
app.listen(3000);
サーバー設定の例:
攻撃手法:
攻撃者がhttps://example.com/account/settings/profile.css
のようなリクエストを送信し、Varnishがこれをキャッシュすると、他のユーザーが同じURLにアクセスした際に攻撃者のセッション情報が表示される可能性があります。
脆弱なコード例:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpSession;
@Controller
public class AccountController {
@GetMapping("/account/settings")
public String accountSettings(HttpSession session) {
if (session.getAttribute("user") == null) {
return "redirect:/login";
}
return "Welcome " + session.getAttribute("user");
}
}
サーバー設定の例:
攻撃手法:
攻撃者がhttps://example.com/account/settings/profile.png
のようなリクエストを送信し、Tomcatがこれをキャッシュすると、他のユーザーが同じURLにアクセスした際に攻撃者のセッション情報が表示される可能性があります。
Cache-Control: no-store
またはprivate
を設定し、共有キャッシュに保存されないようにします。PHPの例:
header("Cache-Control: private, no-store");
Pythonの例(Flask):
@app.route('/account/settings')
def account_settings():
if 'user' not in session:
return redirect('/login')
response = make_response(f"Welcome {session['user']}")
response.headers['Cache-Control'] = 'private, no-store'
return response
Node.jsの例:
app.get('/account/settings', (req, res) => {
if (!req.session.user) {
res.redirect('/login');
} else {
res.set('Cache-Control', 'private, no-store');
res.send(`Welcome ${req.session.user}`);
}
});
まとめ: Web Cache Deception攻撃は、サーバーが動的コンテンツを誤ってキャッシュするように誘導する攻撃です。キャッシュ制御ヘッダーの適切な設定、URL構造の管理、キャッシュサーバーの設定の最適化などの防止策を講じることで、この脆弱性を効果的に防ぐことが可能です。各プラットフォームや言語に共通する問題であるため、これらの対策を適用することが推奨されます。