/* ── BOTTOM NAV (Mobile-first, TASK 2) ── */ :root{ --nav-h: 56px; --bottom-nav-h: calc(56px + env(safe-area-inset-bottom)); } body { padding-bottom: var(--bottom-nav-h); } /* Top nav: hidden on mobile, shown on desktop */ .top-nav{ display:none; } @media(min-width:700px){ .top-nav{ display:flex;align-items:center;gap:0;padding:0; border-bottom:1px solid var(--border); position:sticky;top:0;background:var(--bg);z-index:100;overflow-x:auto; } body { padding-bottom: 0; } .bottom-nav { display:none !important; } } /* Bottom nav: always visible on mobile */ .bottom-nav{ position:fixed;bottom:0;left:0;right:0; background:var(--surface); border-top:1px solid var(--border); display:flex;align-items:stretch; height:var(--bottom-nav-h); padding-bottom:env(safe-area-inset-bottom); z-index:200; -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px); } .bottom-nav-item{ flex:1;display:flex;flex-direction:column;align-items:center; justify-content:center;gap:2px; border:none;background:none;cursor:pointer; color:var(--muted);font-family:var(--mono);font-size:8.5px; letter-spacing:.5px;padding:6px 2px; transition:color .18s;position:relative; -webkit-tap-highlight-color:transparent; min-width:0; } .bottom-nav-item .bni-icon{font-size:18px;line-height:1;transition:transform .18s} .bottom-nav-item.active{color:var(--green)} .bottom-nav-item.active .bni-icon{transform:scale(1.15)} .bottom-nav-item .bni-badge{ position:absolute;top:4px;right:calc(50% - 14px); background:var(--green);color:#000;font-size:7px;font-weight:700; padding:1px 3px;border-radius:2px;display:none; } .bottom-nav-item .bni-badge.show{display:block} /* Active indicator bar on top of item */ .bottom-nav-item::before{ content:'';position:absolute;top:0;left:20%;right:20%; height:2px;background:var(--green);border-radius:0 0 2px 2px; transform:scaleX(0);transition:transform .18s; } .bottom-nav-item.active::before{transform:scaleX(1)} /* page needs top padding adjustment */ .page{min-height:calc(100vh - var(--bottom-nav-h));} @media(min-width:700px){ .page{min-height:calc(100vh - 41px);} } /* Swipe hint shimmer on first load */ @keyframes swipeHint{ 0%{transform:translateX(0);opacity:.7} 50%{transform:translateX(-6px);opacity:1} 100%{transform:translateX(0);opacity:.7} }
VAULT LAB v1.0 — Hacker Learning Terminal
⚠ 教育目的のみ — すべての攻撃デモはブラウザ内サンドボックスで動作します。実際のシステムへの適用は違法です。
White Hat
Learning Platform
VAULT自体を「教材」として使い、本物の暗号・攻撃・防御を体験する。
WebCrypto APIで実際に動く — シミュレーションではなく実行。
Attack Simulator
SQLi / XSS / Hash Cracking / CSRF を体験。攻撃者の視点を理解する。
進行中
+40 XP
🔐
Crypto Playground
AES-256-GCM / PBKDF2 / ECDH をライブ実行。VAULTの暗号エンジンを解剖。
進行中
+50 XP
🏴
CTF Challenge
Base64・ROT13・Hash解析・暗号判定。フラグを取得してバッジを獲得。
0 / 6 完了
+120 XP
🎖
Skill Passport
習熟度レーダー・XPシステム・バッジコレクション。成長を可視化。
0 XP
Level 1
🎯
Threat Model
STRIDE脅威分析・攻撃ツリー・Vaultへの攻撃経路を可視化。
対話型
+30 XP
📡
Packet Analyzer
JWT解析・HTTPヘッダー解剖・Cookie属性・リクエスト改ざん体験。
対話型
+30 XP
📊
Security Score
Vaultのセキュリティ設定を評価。改善推奨とリスクを可視化。
ライブ分析
+20 XP
このラボについて
$ 全処理はブラウザ内で完結。外部サーバーへのデータ送信なし。
$ WebCrypto APIを直接呼び出し — 本物の暗号結果が出力されます。
$ CTFフラグを取得すると自動でXPとバッジが付与されます。
$ 学習後にClaude Codeで残りモジュールを拡張予定。
Attack Simulator — 攻撃者の視点を体験する
⚠ 教育目的のみ。ブラウザ内サンドボックスで動作。実際のシステムへの適用は違法です。
SQL インジェクション体験
脆弱なログインフォーム。ユーザー名に特殊な文字列を入力するとSQLクエリを操作できます。
試してみる: admin' -- または ' OR '1'='1
SELECT * FROM users WHERE
username = 'admin'
AND password = '*****'
// ログイン試行を待っています...
🏴
FLAG-SQLI-001
SQL インジェクション基礎を習得
+20 XP
⬇ 防御版: プリペアドステートメント
// ❌ 脆弱なコード
query = "SELECT * FROM users WHERE username = '" + input + "'"

// ✅ 安全なコード (プリペアドステートメント)
stmt = db.prepare("SELECT * FROM users WHERE username = ?")
stmt.execute([input])  // inputはデータとして扱われる
クロスサイトスクリプティング体験
コメント欄にHTMLタグやJavaScriptを入力してみましょう。
試してみる: <script>alert('XSS')</script> または <img src=x onerror="alert(1)">
❌ 脆弱 (innerHTML)
レンダリング結果:
✅ 安全 (textContent)
← 同じ入力を使用
レンダリング結果:
// 入力を待っています...
🏴
FLAG-XSS-001
XSS攻撃と防御の違いを理解
+20 XP
// ❌ 脆弱: ユーザー入力をそのままHTMLに挿入
element.innerHTML = userInput

// ✅ 安全: テキストとして扱う
element.textContent = userInput

// ✅ または DOMPurify でサニタイズ
element.innerHTML = DOMPurify.sanitize(userInput)
パスワードハッシュ強度比較
同じパスワードを異なるアルゴリズムでハッシュ化。攻撃者が解析するのにかかる時間を比較します。
MD5
即座
SHA-1
即座
SHA-256
数秒
PBKDF2×1K
PBKDF2×200K
年単位
// 「ハッシュを生成」をクリック...
🏴
FLAG-HASH-001
ハッシュアルゴリズムの強度を理解
+20 XP
クロスサイトリクエストフォージェリ
CSRFトークンなし: 悪意あるサイトからのリクエストがそのまま処理される。
CSRFトークンあり: 正規のリクエストのみを受け付ける。
CSRFトークン保護:
✅ 正規サイト (vault.app)
ログイン済みユーザーとして送金リクエスト
⚡ 攻撃者サイト (evil.com)
あなたを騙して送金させようとする
<form action="vault.app/transfer"
      method="POST">
  <input name="amount" value="99999">
  <!-- 自動送信スクリプト -->
</form>
// アクションを待っています...
🏴
FLAG-CSRF-001
CSRF攻撃と防御メカニズムを理解
+20 XP
Crypto Playground — WebCrypto API ライブ実行
暗号化・復号をライブ実行
VAULTがパスワードデータを保護するのと同じアルゴリズム。ブラウザ内で実際に暗号化が走ります。
SALT (16B)
IV (12B)
CIPHERTEXT
AUTH TAG
// 「暗号化」をクリックして実行...
なぜ改ざんが検知できるのか
GCM (Galois/Counter Mode) は暗号化と同時に認証タグを生成します。
暗号文の1ビットでも変わると、タグが一致しなくなり復号が失敗します。
これにより機密性完全性を同時に保証します。
🔑
Key
PBKDF2で
マスターPWから生成
🎲
IV (nonce)
毎回ランダム
再利用禁止
🏷
Auth Tag
改ざん検知
128bit
鍵導出関数 — 反復回数と処理時間
反復回数を増やすと処理時間が線形に増加。ブルートフォース攻撃のコストも同様に増加します。
反復回数
200,000
// 反復回数を選択して実行...
攻撃者のGPU(RTX 4090換算)での解析時間推定
// 実行後に表示
楕円曲線ディフィーヘルマン鍵交換
アリスとボブがそれぞれ鍵ペアを生成し、公開鍵を交換するだけで同じ共有秘密を得られます。
👩 ALICE
公開鍵
未生成
共有秘密
👨 BOB
公開鍵
未生成
共有秘密
// 「鍵ペア生成」から開始...
乱数品質 — Math.random() vs crypto.getRandomValues()
Math.random()は予測可能な疑似乱数。パスワード生成には絶対に使ってはいけません。
❌ Math.random()
分布スコア: —
✅ crypto.getRandomValues()
分布スコア: —
// ボタンをクリックして比較...
CTF Challenge — フラグを取得してバッジを獲得
進捗:
0 / 6 クリア0 XP
Base64 デコード
以下のBase64文字列をデコードしてフラグを見つけてください。
ヒント: atob() または Buffer.from(str, 'base64').toString()
RkxBRy1CNjRERUMtMDAx
// フラグを入力してSUBMIT...
🏴
FLAG-B64DEC-001
Base64エンコーディングをマスター
+15 XP
ROT13 解読
ハッシュアルゴリズム識別
JWT トークン解析
暗号文の雪崩効果を観察
k-Anonymity の実装を理解する
Threat Model — Vaultへの攻撃経路を可視化
⚠ 教育目的。実際のVaultはこれらの脅威に対して対策済みです。
脅威カテゴリ別リスク分析
MicrosoftのSTRIDEモデルでVaultの各コンポーネントを分析。
各カードをクリックすると詳細と対策が表示されます。
// 上のカードをクリックして詳細を表示...
攻撃ツリー — マスターパスワード奪取経路
攻撃者がVaultのマスターパスワードを入手しようとする場合の経路ツリー。
ノードをクリックすると対策と難易度が表示されます。
// ノードをクリックして攻撃手法の詳細を確認...
セキュリティ設定チェッカー
各設定をON/OFFすることで、防御できる攻撃ベクターが変化します。
防御されている攻撃ベクター
0
セキュリティスコア
設定を調整してください
Packet Analyzer — HTTPリクエストを解剖する
JWTトークン完全解析 + 脆弱性デモ
JWTをペーストまたはサンプルを使用
// JWTを入力してデコード...
⚠ JWTは暗号化されていない — Base64エンコードのみ。
誰でもペイロードを読める。秘密情報はペイロードに入れてはいけない。
保護されているのは改ざん検知のみ(正しい署名鍵があれば)。
セキュリティHTTPヘッダー解析
セキュリティ関連HTTPヘッダーの役割と、設定漏れによる攻撃リスクを確認します。
// ヘッダーを入力して解析...
HTTPリクエスト改ざん体験
擬似的なAPIリクエストを編集して、サーバーがどう反応するか体験します。
ATTACK VECTORS DETECTED
リクエストを解析中...
SERVER RESPONSE (simulated)
→ 送信ボタンで擬似レスポンスを表示
Security Score — リアルタイムセキュリティ評価
セキュリティスコア詳細
0 /100
改善推奨 (優先順位順)
30日間のセキュリティスコア推移
Security Coach — リアルタイムパスワード強度分析
// パスワードを入力して解析...
Security Timeline — セキュリティアクション履歴
期間:
Skill Passport — あなたのホワイトハッカースキル
🔰
Curious
0 XP — 次のレベルまで 200 XP
暗号 Web攻撃 ツール 脅威分析 認証
BADGES
NEXT STEPS — 次に学ぶべきこと