
露出保護されたセキュリティスキャンのためのコンテンツブラインドリバースプロキシ
コンテンツブラインド型セキュリティスキャンのためのローカルリバースプロキシ。
Go · ローカルHTTPS · HTTP & WebSocket · Tor / SOCKS5
設計思想 / 仕組み / クイックスタート / 証明書 / Tor / CAPTCHA / エビデンス / 開発
セキュリティテストは振る舞いを扱う学問です。アプリケーションが何をするか -- 入力をどう処理し、どのような制御を適用し、何を反射し、どう失敗するか -- が重要です。その分析において、アイデンティティは無関係であるべきです。
AI支援型のセキュリティツールはそう動きません。ターゲット -- そのドメイン、ブランド、組織 -- を見て、意見を形成します。有名なサービスに対しては検出結果を弱めます。ターゲットが誰であるかに基づいて調査を拒否します。特定のベンダーと結びついたパスをテストしないことがあります。AIがオペレーターに属する判断を下しており、しかもコンテキストに基づいて判断し、振る舞いには基づいていません。
これは間違った軸です。スコープを認可するのはオペレーターです。振る舞いを評価するのはツールです。これらは異なる責任であり、一つに統合されるべきではありません。しかし今日、AI支援型ツールはすべて、ターゲットの完全なアイデンティティをあらゆる判断 -- 何をテストするか、どこまで踏み込むか、報告するかどうか -- に組み込んでいます。
Blinderはその出発点です。実用的なツールであると同時に、テストはコンテキストから分離されるべきだという立場でもあります。これはこの考えを世に出すための初期の試みです。このアプローチに共感していただけるなら、より良い実装、コントリビューション、あるいは線引きをどこに置くべきかという対話を歓迎します。
アイデンティティを剥ぎ取ることは、コンテンツを剥ぎ取ることではありません。多くの素朴なアプローチがここで破綻します。脆弱性はレスポンスコンテンツの変化として観測可能です -- エラーメッセージ、反射された入力、セッションが到達すべきでないデータ、サーバーサイドの評価を明らかにする計算結果など。プロキシがこのコンテンツを剥ぎ取れば、テスターが探しているエビデンスを隠してしまいます。
要件は外科的です。アイデンティティを除去しつつ、振る舞いのシグナルを保持すること。誰にも属さないが、オリジナルとまったく同じように振る舞うページ -- 悪い振る舞いをするときも含めて。
Blinderは、AIスキャナー(またはブラウザ)とターゲットの間に位置するローカルHTTPSリバースプロキシです。ドメイン、ブランド、組織名、メールアドレス、IPアドレスといったアイデンティティを書き換えつつ、アプリケーションの機能的な振る舞い -- エラー、反射、セキュリティ制御、ステータスコード、コンテンツ構造 -- を保持します。
下流のAIにとって、ターゲットはhttps://127.0.0.1:8099にある匿名のローカルホスト型アプリケーションです。認識すべきブランドはなく、意見を形成すべきドメインもありません。AIはアプリケーションが何をするかをテストし、何であるかはテストしません。
これがコンテンツブラインド型スキャンです。ターゲットが誰であるかはオペレーターが制御し、AIは何をするかに集中します。
置換コンテンツは正確性の一部です。表示用の中立的なフィラー、アプリケーションデータ用の可逆的な値、そして保持される診断情報と制御の振る舞い。生成された削除通知はページに含めるべきではありません。
| コンテンツスクラビング | 表示テキストは中立的な散文フィラーに置換。インタラクティブ要素(ボタン、ラベル、フォームコントロール)と診断コンテンツ(エラーメッセージ、スタックトレース、反射されたマークアップ)は保持。アイデンティティトークン、ドメイン参照、Cookie値はHTTPボディ、ヘッダー、WebSocketテキスト全体で書き換え。--preserve-contentはアイデンティティのみのスクラビングのために元の表示テキストを保持。 |
| リソース整合性 | 参照ごとに元のSRIを検証し、書き換えられたリソースに対して再計算。対応するCSPハッシュも変換。バージョン付き参照は提供されるバイトを束縛し、外部リソースの整合性は保持。 |
| レスポンスキャッシュ | 上流/下流で別々のキャッシュバリデータ。304再検証はセキュリティポリシーヘッダーをマージ。Vary対応のエビクション。 |
| セッション処理 | 値ごとのスクラビングを伴う可逆的なCookie名。--extra-originによるマルチオリジンルーティング。決定論的なエイリアスホスト名、Hostヘッダールーティング、CORSオリジン変換。 |
| CAPTCHAリレー | オペレーター向けのチャレンジキューと分離されたプロバイダーオリジン。Tor経由のリソースはプロバイダーのCookie、CSP、CORSをターゲットおよびオペレーターから分離して保持。 |
| プライベートルーティング | リモートホスト名解決を伴うTor SOCKS5経由の上流HTTPおよびWebSocket。Torの失敗はハードエラーであり、サイレントなフォールバックは行わない。 |
| ローカルHTTPS | 90日間の有効期間と自動更新を備えたローカルCA。セッションリーフ証明書はオンザフライで署名。CAを一度信頼すれば、オリジンの追加やエイリアスの変更で再信頼は不要。エフェメラルモードも利用可能。 |
| エビデンス | ジャーナルベースの永続化を伴うスクラブ前HAR、リクエストごとのスクラブ/リークカウントを含むリクエストマニフェスト、ドメインマッピング、スクラブレポート。ペアレスポンス比較はバイトサイズの忠実性と、コンテンツ/ステータスの変化がマスキングを生き延びるかを確認。シグナル保持チェックは検証済みの振る舞いと残存する欠陥を記録。 |
実装状況と既知の制限についてはサポートされる振る舞いとデリバリーゲートを参照してください。
**Go 1.26+**でビルドします。バイナリには外部ランタイム依存はありません。
git clone https://github.com/Splinters-io/blinder.git
cd blinder
make build
./blinder --preflight
OS固有の証明書に関するアドバイスに従い、セッションを開始します。
capture_dir=$(mktemp -d)
./blinder --target https://your-authorized-target.example \
--identity YourOrganisation \
--har "$capture_dir/session.har" \
--output "$capture_dir/output"
ブラウザまたはスキャナーを**https://127.0.0.1:8099**に向けます。--identityフラグを繰り返して複数のアイデンティティトークンを追加します。Ctrl-Cで停止するとセッションのエビデンスが保存されます。
--config(-c)を使用してYAMLファイルからデフォルトを読み込みます。CLIフラグはファイルを上書きします。
# blinder.yaml
listen: "127.0.0.1:9443"
target: "https://example.com"
alias: "target-001.local"
identity:
- "ExampleCorp"
- "example.com"
output: "/tmp/blinder-output"
captcha_config: "captcha.yaml"
no_verify_tls: true
tor:
enabled: false
addr: "127.0.0.1:9050"
har:
path: "/tmp/session.har"
max_body: 10485760
./blinder -c blinder.yaml
# override the listen port from the file:
./blinder -c blinder.yaml --listen 127.0.0.1:7777
Blinderは初回実行時にローカルCA(Certificate Authority)を生成し、それを使ってセッション固有のリーフ証明書に署名します。CAを一度信頼すれば、現在および将来のすべてのエンドポイント -- 後から追加される追加オリジンも含む -- がセットアップを再実行することなく自動的に信頼されます。
| プラットフォーム | セットアップ |
|---|---|
| macOS | 表示される--trust-certコマンドを実行し、CAフィンガープリントを確認してユーザーKeychainの信頼を承認します。一度きりのセットアップです。 |
| Ubuntu / Linux | 表示されるcurl --cacertコマンドを使用するか、ブラウザ/スキャナーのトラストストアにCA証明書をインストールします。 |
--cert-dir DIRで任意のCAストアを指定できます。CAは90日間永続し、自動更新されます。--ephemeral-certはCAなしの一時的な自己署名リーフを生成します。プリフライトの終了コード2はプラットフォームの信頼設定が必要であることを意味しますが、独自のCAファイルを使用するクライアントは引き続き正常に接続できます。
追加オリジンの追加、エイリアスの変更、CAPTCHAプロバイダーの再設定は、同じCAで署名された新しいリーフ証明書を生成します -- 再信頼は不要です。プリフライトはリッスンホスト、プライマリエイリアス、設定された追加オリジンエイリアス、およびCAPTCHAが設定されている場合はオペレーターと具体的なチャレンジホスト名の信頼を報告します。--torを指定すると、プリフライトには設定されたプロバイダーエイリアスも含まれます。
CAストアはまた、証明書の更新とは独立した、リソース参照の所有権のためのプライベートなversion-signing.keyも保持します。期限切れの参照が認識可能であり続けるよう、再起動をまたいでこれを保持してください。--ephemeral-certはTLSを一時的に保ちますが、リソース参照の所有権はデフォルトストアに引き続き永続します。
Torサービスを起動してブートストラップを待ち、そのSOCKSエンドポイントを選択します。
./blinder --target http://your-service.onion \
--tor --tor-addr 127.0.0.1:9050 \
--identity YourOrganisation
クリアネットのターゲットも同じルートを使用できます。ターゲットのTLS検証は有効なままです。Torの失敗は、ターゲットへの直接接続にフォールバックすることなくエラーを返します。
ターゲットがCAPTCHAチャレンジを返すと、Blinderはそれをオペレーター用にキューに入れます。プロバイダーは--captcha-configで設定します。
version: 1
captcha:
providers:
- hcaptcha
起動時に表示されるブラウザログインURLを開きます: https://blinder-operator.localhost:<port>/__blinder/captcha/login?token=…。この分離されたローカル専用オリジンがオペレーターセッションを保持します。生のチャレンジコンテンツは、期限付きのビュー機能を通じて独自の<challenge-id>.blinder-challenge.localhostオリジンで実行されます。オペレーターCookieはオペレーターオリジンに留まります。APIクライアント向けにBearer認証も引き続き利用可能です。証明書プランニングにはチャレンジワイルドカードが含まれます。選択したブラウザのオペレーター、チャレンジ、プロバイダーホスト名に対する信頼を確認してください。オペレーターと証明書ガイドを参照してください。
--torを指定すると、設定された各route-with-targetプロバイダーオリジンは独自のhttps://captcha-<hash>.localhost:<port>アドレスを取得し、ターゲットのSOCKSトランスポートを使用します。静的HTML参照、ベースURL、リフレッシュナビゲーションはこれらのルートを使用します。境界付きヘルパーは、CSPのないプロバイダードキュメント内の動的fetch、XHR、URLセッターもルーティングします。プロバイダーのスクリプトバイトと整合性メタデータは変更しません。強制ポリシーまたはレポート専用ポリシーを持つドキュメントにはヘルパーは提供されません。プロバイダーのエラーと実際のCORS判断は可視のままで、Cookieはブラウザの制御下に留まります。旧/__blinder/captcha/resエンドポイントはターゲットおよびオペレーターオリジンで404を返します。
組み込みプロファイルはhCaptcha、reCAPTCHA、Turnstileをカバーします。カスタムプロバイダーは明示的なresource_origins、オプションのresource_url_regex、opaque_fields、submissionsを使用します。リレーされるすべてのリクエストはそのスコープに対してチェックされます。ダイレクトモードはプロバイダー参照をそのまま残し、tor_policy: directは明示的なTor例外のままです。
Chromeは合成オペレーターフローを完了しました。13件のプロバイダーリクエストすべてがリレーを使用し、元のPOSTは正確なソリューショントークン、セッション、更新されたCSRFで再開されました。別のクロスサイトLax-Cookieケースでは、ダイレクトプロバイダーのHTTP 400拒否が保持されました。これは境界付きのローカル受け入れです。CSP制限されたチャレンジ、他の動的ローディングAPI、実際のエイリアス信頼、実プロバイダーでの人間による完了、ライブTor/オニオン受け入れは未解決のままです。再現可能なブラウザチェックはこれらのゲートを個別に記録します。