セキュアな「x-ch-no-bypass」トークンを使用して、DNSバイパス攻撃を防御する。
はじめに
このガイドでは、DNSバイパス攻撃から防御する方法の概要と具体例を説明します。CrowdHandlerのどの連携機能においても、x-ch-no-bypassヘッダーの実装は必須ではありませんが、実装することでユーザー認証の追加の層が確保されるため、推奨されます。
この記事は、どのような統合タイプに関連していますか?
「DNSバイパス攻撃」とは、具体的にどのようなものを指すのでしょうか?
お好みのCDNにCrowdHandlerを統合することで、CrowdHandlerによるチェックを回避することは困難になりますが、ウェブインフラに関連するネットワーク情報を突き止めることができる熟練したユーザーであれば、CDNのエンドポイントを迂回してトラフィックを送り、CrowdHandlerの統合を含むCDNが提供するすべての保護機能を回避できる可能性があります。
仕組み
設定が完了すると、CrowdHandler 連携機能は、アプリケーションに転送されるすべてのリクエストに「x-ch-no-bypass」という名前のヘッダーを追加します。このヘッダーの値には、セキュリティ保護されたバイパス防止トークンが設定されます。最小限のコードで、Web アプリケーションを構成し、リクエストにこのヘッダーとトークンが含まれているかどうかを確認できるようにすることで、CrowdHandler による検証を経たユーザーのみがアプリケーションにアクセスできるようにすることができます。
トークンはどこで確認できますか?
DNS連携機能をご利用の場合は、トークンはCrowdHandler管理コンソールの、保護対象となるWebアプリケーションのドメイン設定画面で確認できます。トークンの値は、「No-Bypass Token」フィールドに保存されています。
その他のCDN(Akamai、Cloudflare、CloudFront)との連携については、それぞれのインストールガイドに、バイパス防止トークンの設定方法が記載されています。
統合事例
x-ch-no-bypass リクエストヘッダーの存在と値の確認は、ほとんどのプログラミング言語や Web サーバーで簡単に実行できます。以下に、広く使われているさまざまな言語や Web サーバーにおける実装例をいくつか示します。
Apache
RewriteEngine On
# block if request header x-ch-no-bypass value isn't matched
RewriteCond %{HTTP:x-ch-no-bypass} !^(YOURTOKENVALUE)$
RewriteRule ^ - [F]
Nginx
location / {
if ($http_x_ch_no_bypass != "YOURTOKENVALUE") {
return 403;
}
proxy_pass http://app:3000/;
}
Express.js
app.get('/', (req, res) => {
if (req.header('x-ch-no-bypass') !== "YOURTOKENVALUE") {
res.status(403).send("Sorry! You can't see that.")
}
res.sendFile(__dirname + "/views/index.html");
})
PHP
function getRequestHeaders() {
$headers = array();
foreach($_SERVER as $key => $value) {
if (substr($key, 0, 5) <> 'HTTP_') {
continue;
}
$header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
$headers[$header] = $value;
}
return $headers;
}
$headers = getRequestHeaders();
if($headers['X-Ch-No-Bypass'] != "YOURTOKENVALUE") {
header("HTTP/1.1 403 Forbidden" );
exit;
}
Python (Django)
from django.http import HttpResponseForbidden
from django.http import HttpResponse
def index(request):
chBypassKey = request.META.get('HTTP_X_CH_NO_BYPASS')
if (chBypassKey) != "YOURTOKENVALUE" :
return HttpResponseForbidden()
else :
return HttpResponse("Hello world!")