SSRF攻撃について
SSRF(Server-Side Request Forgery、サーバーサイドリクエストフォージェリ)攻撃は、攻撃者がサーバー側のリクエストを不正に操作して、意図しない外部または内部リソースへのリクエストを発生させる攻撃手法です。これにより、攻撃者は通常アクセスできない内部ネットワークや、保護されたリソースにアクセスできるようになる可能性があります。SSRF攻撃は、Webアプリケーションがユーザーからの入力に基づいてHTTPリクエストを生成する際に発生することが多く、データの漏洩や内部システムのスキャンに悪用されます。
脆弱なコード:
<?php
$url = $_GET['url'];
$response = file_get_contents($url);
echo $response;
?>
攻撃手法:
攻撃者がurl
パラメータにhttp://localhost/admin
のような内部URLを指定することで、内部ネットワーク上のサービスにアクセスできます。また、file://
スキームを利用してサーバー上のローカルファイルを読み取ることも可能です。
脆弱なコード:
from flask import Flask, request
import requests
app = Flask(__name__)
@app.route('/fetch')
def fetch():
url = request.args.get('url')
response = requests.get(url)
return response.content
if __name__ == '__main__':
app.run()
攻撃手法:
攻撃者がurl
パラメータにhttp://169.254.169.254/latest/meta-data/
のようなAWSのメタデータサービスへのリクエストを送信すると、クラウドインスタンスに関する機密情報が漏洩する可能性があります。
脆弱なコード:
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/fetch', async (req, res) => {
const url = req.query.url;
const response = await axios.get(url);
res.send(response.data);
});
app.listen(3000);
攻撃手法:
攻撃者がurl
パラメータに内部IPアドレスを指定することで、内部ネットワーク上のサービスやAPIにアクセスできるようになります。
脆弱なコード:
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SSRFServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = request.getParameter("url");
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
response.getWriter().println(content.toString());
}
}
攻撃手法:
攻撃者がurl
パラメータに内部ネットワーク上のサービスURLを指定することで、内部リソースに対する情報を取得したり、リクエストを送信することができます。
http
やhttps
以外のスキームを禁止し、file://
やgopher://
のような不正なスキームを無効化します。まとめ: SSRF攻撃は、サーバー側のリクエストを不正に操作して内部リソースや保護されたリソースにアクセスさせる攻撃です。ユーザー入力の厳格な検証、ネットワークレベルでのアクセス制限、プロキシの使用、リクエストのタイムアウト設定などの防止策を適用することで、この脆弱性を効果的に防ぐことができます。どの言語やプラットフォームでも、これらのベストプラクティスを実装することが推奨されます。