[Joke] ローカルネットワークに対するクロスオリジンの攻撃からシステムを守る簡単な方法

インターネット上に公開されているわなサイトを経由して社内イントラネットなどのローカルネットワークへXSSCSRFなどのクロスオリジンでの攻撃を仕掛けようという試みは古くから存在します。現実にこれらが行われたという話は聞いたことはありませんが、理論上は可能であるという話をよく聞きます。対策としてまず検討すべきは、社内システムであっても通常のシステム同様に脆弱性を生まないようセキュアなものにするということです。それらが難しい場合には、少しの手間でローカルネットワークに対するクロスオリジンでの攻撃を低減させることができます。

フィドラでクロスオリジンからの攻撃を低減させる手順

Fiddler を起動し「Rules」メニューから「Customize Rules...」をクリックします。エディターが立ち上がってルール用のFiddlerScriptの編集画面が出てきますので、以下を追記します。

function isLocalServer(host:String):Boolean {
    // TODO: 環境に合わせてここを修正して下さい
    const localServers = ["server-name-1", "server-name-2"];
    var re = /^([\d]{1,3})\.([\d]{1,3})\.([\d]{1,3})\.([\d]{1,3})$/;
    var m = re.exec(host);
    var i;
    // プライベートIPアドレスのホストはローカルのサーバーとみなす
    if (m !== null) {
        m[1] = m[1]|0;
        m[2] = m[2]|0;
        m[3] = m[3]|0;
        m[4] = m[4]|0;
        if (m[1] > 255 || m[2] > 255 || m[3] > 255 || m[4] > 255) return false;
        if (m[1] === 10) return true;
        if (m[1] === 172 && (m[2] >= 16 && m[2] <= 31)) return true;
        if (m[1] === 192 && m[2] === 168) return true;
    }
    // ローカルサーバーの一覧に存在するかチェック
    for (i = 0; i < localServers.length; i++) {
        if (host.Equals(localServers[i]) ){
            return true;
        }
    }
    return false;
}

class Handlers
{

    // 省略

    static function OnBeforeRequest(oSession: Session) {

        // 省略
       
        // ターゲットがローカルサーバー
        if (isLocalServer(oSession.hostname)) {
            var from = oSession.oRequest.headers["origin"];
            if (from !== "") {
                from = from.replace(/^https?:\/\//,"");
            } else {
                var m = /\/\/([^\/]+)\//.exec(oSession.oRequest.headers["Referer"]);
                if (m !== null) {
                    from = m[1].replace( /^[^@]+@/,"");
                }
            }
            // 呼び出し元がローカルサーバーではない
            if (!isLocalServer(from)) {
                FiddlerApplication.Log.LogFormat("Blocked {0} from {1}", oSession.fullUrl, from);
                oSession.utilCreateResponseAndBypassServer();
                oSession.oResponse.headers.Add("Content-Type", "text/plain");
                oSession.oResponse.headers.HTTPResponseCode = 404 ;
                oSession.oResponse.headers.HTTPResponseStatus = "404 Not Found";
            }
        }
    }
}

たったこれだけで、外部のわなサイトを経由したクロスオリジンの攻撃からローカルシステムをある程度守れます。

まとめ

やっていることは、通常は社外の公開サーバーをRefererやOriginとして社内に対してリクエストが発行されることはないので、それを検知した場合に404応答を返しているだけです。ただし、もちろんのことながら、ReferrerやOriginがつかない状況も頻繁に発生するので、そういった場合にはこの方法では攻撃を防ぐことはできません。繰り返しになりますが、社内システムであっても社外のシステム同様にきちんと脆弱性への根本的な対策を行っておくべきでしょう。