アプリケーションに、ログイン、登録、パスワードのリセット/回復、確認リンクの再送信などの基本的な機能や、サーバー リクエストを必要とするその他の特定の機能が含まれている場合、ブルート フォース攻撃やサービスへの相当な負荷の生成に対するメカニズムを実装することが重要です。このようなメカニズムがないと、アプリケーションはユーザーに過剰な数の電子メール/OTP を送信するなど、さまざまな脅威に対して脆弱になる可能性があり、経済的および評判上の損害につながる可能性があります。
多くのWeb アプリケーションには適切なレート制限手段が欠如しており、支払いモデルに基づいたリクエスト数の制限など、ビジネス ロジックによって課される制限のみに依存しています。ただし、一部のアプリケーションには、特にログイン試行、登録、その他の重要な機能などの操作に対してレート制限が組み込まれています。これらの実装は、多くの場合、IP アドレス追跡のための X-Forwarded-For ヘッダーに依存します。
簡単な例を説明するために、 Flaskでこのコード スニペットを思いつきました。
from flask import Flask, request, jsonify from flask_limiter import Limiter from flask_limiter.util import get_remote_address app = Flask(__name__) limiter = Limiter( app, key_func=get_remote_address, storage_uri="memory://",) def get_ipaddr(): # Retrieve the client's IP address from the request # X-Forwarded-For header is used to handle requests behind a proxy ip_address = request.headers.get('X-Forwarded-For', request.remote_addr) return ip_address # Rate limit to 5 requests per minute per IP @limiter.limit("5 per minute") @app.route('/') def index(): ip_address = get_ipaddr() return ip_address
次のセクションでは、アプリケーションでレート制限をテストし、バイパスするためのさまざまなアプローチについて説明します。
この種の脆弱性についてアプリを効率的にテストするには、自動化が強力なツールです。これは、Python などのスクリプト (私がよく行うように) を使用するか、Burp Suite などのツール (テスターやサイバーセキュリティ専門家にとって優れたツール) を使用することで実現できます。また、Postman のようなツールを使用すると、チェックを比較的簡単に自動化できる場合もあります。
X-Originating-IP: 127.0.0.1
送信するリクエストごとに異なる IP 値を使用します。
二重の X-Forwared-For ヘッダーを使用します。
X-Forwarded-For: X-Forwarded-For: 127.0.0.1
別のヘッダーでも同じことを試してください。
X-Originating-IP: 127.0.0.1 X-Remote-IP: 127.0.0.1 X-Remote-Addr: 127.0.0.1 X-Client-IP: 127.0.0.1 X-Host: 127.0.0.1 X-Forwared-Host: 127.0.0.1
ユーザーエージェント、コンテンツタイプ、受け入れ言語など、またはクッキーなど、ユーザー識別子として使用できるものを変更してみてください。
IP ごとに 3 回の試行というレート制限がある場合は、3 回の試行ごとにヘッダー (またはリクエスト内の他のヘッダーやパラメーター) の IP 値を変更します。
送信するパラメータに追加してみてください
%00, %0d%0a, %0d, %0a, %09, %0C, %20
例えば
param1=value1%%0d%0a param2=value2%00
たとえば、電子メール検証に OTP をリクエストしていて、試行回数が 3 回しかない場合は、その 3 回の試行回数を使用します。
[email protected] [email protected]%00 [email protected]%0d%0a And so on
たとえば、/API/v1/signup エンドポイントをテストしている場合は、/Signup、/SignUp、/sign-up に対してブルート フォースを実行してみてください。 (上記の) 空白文字を元のエンドポイントに追加してみてください。
/api/v1/resetpassword エンドポイントのリクエストに制限がある場合は、いくつかのクエリ パラメータを追加してブルート フォース攻撃を試みます。レート制限に達したら、たとえば /api/v1/resetpassword?param1=value1 を試してください。
アプリのロジックに欠陥がある可能性があります。各試行または一連の試行の前にアカウントにログインすると、IP のレート制限がリセットされ、パスワード ブルート フォース攻撃を続けることができます。ログイン機能をテストしている場合は、設定でピッチフォーク攻撃を使用して Burp Suite でこれを実行できます (または、このための独自のスクリプトを作成することもできます)。
以下は、POW を取得するためだけに X-Forwarded-For ヘッダーの簡単なチェックを自動化する方法の例です。
from random import randint import requests import json url = "https://yourapp.net/api/v1/regconfirm-resend" data = { "email": "[email protected]" } N = 100 def generate_random_ip(): return '.'.join( str(randint(0, 255)) for _ in range(4) ) for _ in range(N): headers = { "Host": "yourapp.net", "Content-Type": "application/json", "X-Forwarded-For": generate_random_ip() } response = requests.post(url, headers=headers, data=json.dumps(data)) print(headers) print(f"Status Code: {response.status_code}, Response: {response.text}")
考えられる解決策は、Cloudflare とそのメカニズムの使用です。詳細な説明は、 ここでrestoring-original-visitor-ipsを参照してください。その防御メカニズムの概要のみを説明します。
元の訪問者の受信 IP アドレスに依存するアプリケーションを使用する場合、デフォルトで Cloudflare IP アドレスが記録されます。元の訪問者の IP アドレスは、CF-Connecting-IP と呼ばれる追加された HTTP ヘッダーに表示されます。 Web サーバーの指示に従うことで、元の訪問者の IP アドレスをオリジン サーバーに記録できます。リクエストがオリジンサーバーに到達したときにこの HTTP ヘッダーが使用できない場合は、変換ルールと管理された変換の構成を確認してください。
擬似IPv4がヘッダーの上書きに設定されている場合 - Cloudflareは、CF-Connecting-IPv6ヘッダー内の実際のIPv6アドレスを保持しながら、既存のCf-Connecting-IPおよびX-Forwarded-Forヘッダーを擬似IPv4アドレスで上書きします。
注:このような防御メカニズムを実装する場合は、徹底的なテストを実行することを忘れないでください。このアプローチは、その後クラスター全体に適用される可能性があり、不必要な特定の機能やマイクロサービスに悪影響を与える可能性があります。一言で言えば、セキュリティ侵害を修正する際は、アプリケーション全体に影響を与える可能性があるため、注意が必要です。システムのどの部分が悪影響を受ける可能性があるかを分析し、本番環境に変更を出荷する前にすべてをテストします。
ここでも公開されています。