turtle-harden について
Turtle Harden は、セキュア設計とコードレビュー向けのセキュリティ強化スキルです。リリース前や、ユーザー入力・機密データ・外部サービスを扱うコードの確認に使え、攻撃面の把握から多層防御、攻撃ベクトルの検査、最終検証まで段階的に進めます。
主な機能
- 01入出力点とデータフローの把握
- 02入力・出力・エラーへの防御
- 03認証とテナント分離の強化
- 0419 種類の高度な攻撃ベクトルの確認
- 05ビルド検証とレポート作成
活用シーン
- 01リリース前の機能レビューと強化
- 02ユーザー入力を扱うコードの検査
- 03マルチテナント境界の安全性評価
- 04外部サービス連携の防御確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ autumnsgrove/ lattice --skill turtle-hardenインストール後、Claude Code で/turtle-hardenを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/attack-surface.mddeep-defenses.mdexotic-vectors.mdfoundational-defenses.mdverification-report.md詳細
Turtle Harden 🐢
カメは急ぎません。太古からの忍耐強さで森の地面を進み、根も、石も、影も、一つずつ確かめます。その甲羅は後付けされた鎧ではありません。背骨と融合した骨に、板状の骨の上へケラチンが重なった、内側から育まれた三層の防御です。これこそが、セキュア・バイ・デザインの意味です。出荷前に付け加えるのではなく、対象そのものに組み込まれた保護です。アライグマが散らかった後始末をし、クモが戸口に鍵を編み上げる一方で、カメは地面そのものを安全に歩けるようにします。多層防御。すべての層で。常に。
起動するタイミング
- ユーザーが「これを強化して」「安全にして」「セキュリティレビュー」と言ったとき
- ユーザーが
/turtle-hardenを呼び出す、またはカメや強化に言及したとき - 新機能を構築する際、セキュア・バイ・デザインにしたいとき
- 本番環境に何かをデプロイする前
- 既存のコードに潜む、深刻または微妙な脆弱性を監査するとき
- アライグマが表面的な問題を見つけ、さらに深く調べたいとき
- 認証を実装した後(クモが網を編んだら、次はそれ以外をすべて強化します)
- ユーザーが「多層防御」または「セキュア・バイ・デザイン」と言ったとき
- ユーザー入力、ファイルアップロード、機密データを扱うものに取り組むとき
- 外部サービスとやり取りするコード(SSRF のリスク)をレビューするとき
- マルチテナントの境界に関わる作業全般
重要: カメはもともと丁寧です。フェーズを省略してはいけません。急いではいけません。隙間のある甲羅は何も守れません。
組み合わせるもの: まずシークレットをスキャンする raccoon-audit、認証を実装する spider-weave、セキュリティ回帰テストを書く beaver-build
強化の手順
WITHDRAW --> LAYER --> FORTIFY --> SIEGE --> SEAL
| | | | |
Survey Build Harden Attack Lock
Attack Found- Deep Test Down &
Surface ation Defense Defenses Report
フェーズ 1:WITHDRAW(甲羅にこもる)
カメは甲羅にこもり、周囲に目を配りながら、安全な場所から世界を観察します……
何かを強化する前に、何を守るのか、何が脅威となるのかを理解してください。
- 対象範囲を特定します。新しいコード(セキュア・バイ・デザイン)ですか、それとも既存のコード(監査)ですか。どの脅威モデルが当てはまりますか。
- データがシステムに入るすべての入口を洗い出します(URL パラメーター、フォーム、ヘッダー、Cookie、ファイル、WebSocket、API、Webhook)
- データがシステムから出るすべての出口を洗い出します(HTML、JSON、DB 書き込み、外部呼び出し、ログ、リダイレクト)
- 機密データのデータフローを追跡します。認証情報、PII、トークン、支払い情報について、どこから入り、どこに保存され、どこを通り、どこに表示され、どこで消えるのかを確認します
- 技術固有のリスクを評価します。SvelteKit のレイアウトバイパス、CF Workers のシークレット保管、JS のプロトタイプ汚染、D1 のテナント分離
出力: 入口、出口、データフロー、技術固有のリスクを網羅した攻撃対象領域マップ
詳細なリファレンス: references/attack-surface.md を読み込み、入口と出口の完全なチェックリスト、データフローの一覧、技術スタック別のリスクパターンを確認します
フェーズ 2:LAYER
層を重ねるごとに、外殻は強くなります。骨の上にケラチン、背骨の上に骨を重ねるように……
基盤となる防御を適用します。これらは必須です。すべてのコードに、これらの層が必要です。
- 2A. 入力検証 — Zod/Valibot を使った許可リスト、厳密な型、長さと範囲の制限により、すべてのエントリーポイントでサーバーサイド検証を行います。無効な入力は拒否し、暗黙的に型変換しません
- 2B. 出力エンコーディング — すべての出力箇所で、コンテキストに応じてエンコードします(HTML、JS、URL、CSS、JSON)。サニタイズされていない入力に
{@html}を使用しません。リッチテキストには DOMPurify を使用します - 2C. パラメーター化クエリ — SQL での文字列連結は一切禁止します。すべてのクエリで
.bind()を使用し、database.tsの型付きヘルパーを使用します。並列クエリにはPromise.all()を使用します - 2D. 型安全性 — すべての信頼境界で Rootwork ユーティリティを必ず使用します。フォームデータには
parseFormData()、KV/JSON の読み取りにはsafeJsonParse()、catch ブロックにはisRedirect()/isHttpError()を使用します。境界でasによる型アサーションを使用しません。TypeScript の strict モードは最低限の要件であり、Rootwork が最後の砦です。参照:AgentUsage/rootwork_type_safety.md - 2E. エラー処理 — すべてのエラーに Signpost コードを使用します。サーバーエラーには
logGroveError()を使用し、ユーザーへのメッセージは一般的な内容に限定します。列挙攻撃につながる情報を漏らさず、例外を握りつぶしません
出力: すべてのエントリーポイントと出力箇所に基盤となる防御を適用済み
詳細なリファレンス: 5 つすべての基盤レイヤーについて、完全なチェックリスト、コード例、SvelteKit のパターンを確認するには、references/foundational-defenses.md を読み込みます
フェーズ 3:FORTIFY
外殻の各装甲板が次の板と噛み合います。隙間も継ぎ目もなく、突破する手段はありません……
すべてのセキュリティ領域に、深く重層的な強化を適用します。
- 3A–3B. HTTP ヘッダーと CSP — すべてのレスポンスに必須のセキュリティヘッダーを設定します。厳格な nonce ベースの CSP を使用し、フレームワークの情報が漏れるヘッダーを削除します
- 3C. CORS — 厳密な許可リスト検証を行います。オリジンをそのまま反映せず、認証情報と
*を併用しません - 3D–3E. セッションと CSRF — CSPRNG によるセッション ID、HttpOnly/Secure/SameSite Cookie、認証時のセッション再生成を行います。状態を変更するすべてのリクエストに CSRF トークンを使用します
- 3F. レート制限 — 認証エンドポイントとリセットエンドポイントにレート制限を適用します。Cloudflare のエッジルールを設定し、負荷の高い処理の前に制限を適用します
- 3G–3H. 認証と認可 — Argon2id によるハッシュ化を行い、列挙攻撃を防ぎます。PKCE OAuth を使用し、JWT は明示的なアルゴリズムを指定して検証します。認可はレイアウトではなく
hooks.server.tsで強制し、デフォルトで拒否します - 3I. マルチテナント分離 — リクエスト境界でテナントコンテキストを解決します。すべてのクエリを
WHERE tenant_id = ?でスコープし、キャッシュキーにテナント ID を含めます - 3J. ファイルアップロード — ファイルタイプの許可リストとマジックバイト検査を適用します。サーバー側でファイル名を生成し、Web ルートの外に保存します。配信時には Content-Disposition: attachment を設定します
- 3K. データ保護 — TLS 1.2+ と HSTS を使用します。シークレットはソースコードではなく Workers Secrets に保存します。PII を最小限にし、トークンの比較には定数時間比較を使用します
出力: すべてのセキュリティ領域に深く重層的な防御を適用済み
詳細なリファレンス: FORTIFY の 11 個すべてのサブセクション(3A–3K)について、完全なチェックリストとコード例を確認するには、references/deep-defenses.md を読み込みます
Phase 4: SIEGE
甲羅を試してください。攻撃し、押し、あらゆる角度から試してください。耐えたものには価値があります。壊れたものは、敵に見つかる前に発見できたのです……
攻撃者の視点で考えてください。標準的なレビューでは見逃される、微妙で特殊な脆弱性を確認してください。
- 以下の19種類の特殊な攻撃ベクトルをすべて確認します
- それぞれについて、攻撃を頭の中で(安全であれば実際に)試し、防御が機能することを確認します
- 攻撃対象領域が存在するかどうかに基づいて、各項目を CLEAR、FOUND、N/A のいずれかに分類します
確認する攻撃ベクトル: 4A プロトタイプ汚染 · 4B タイミングサイドチャネル · 4C 競合状態(TOCTOU) · 4D ReDoS · 4E SSRF · 4F CRLF インジェクション · 4G Unicode 攻撃 · 4H デシリアライゼーション · 4I postMessage · 4J WebSocket · 4K CSS インジェクション · 4L SVG XSS · 4M キャッシュポイズニング · 4N オープンリダイレクト · 4O HTTP メソッドの改ざん · 4P 二次的脆弱性 · 4Q サプライチェーン · 4R Service Workers · 4S DNS とインフラストラクチャ
出力: すべての特殊な攻撃ベクトルをテストし、脆弱性を特定するか、存在しないことを確認します
詳細なリファレンス: 19種類すべての攻撃ベクトルの完全なチェックリストとコード例については、references/exotic-vectors.md を読み込みます
Phase 5: SEAL
甲羅は完成しました。すべての隙間が塞がれ、すべての板が整いました。亀は耐え抜きます……
最終確認と報告を行います。
- 多層防御への準拠 — セキュリティがネットワーク、アプリケーション、データ、インフラストラクチャ、プロセスの各層にわたって構成されていることを確認します。各重要機能に、独立した制御が2つ以上あることを確認します
- ロギングと監視 — 認証イベント、認可の失敗、検証による拒否が記録されていることを確認します。ログにシークレットや個人を特定できる情報が含まれていないこと、ブルートフォース攻撃や異常を検知するアラートが設定されていることを確認します
- ビルド検証(必須) —
pnpm install && gw ci --affected --fail-fast --diagnoseを実行し、封印する前にリグレッションを修正します - セキュリティスキャン — ハードコードされたシークレット、危険なパターン(
eval、innerHTML、__proto__)、無効化されたセキュリティ機能を grep で検索し、pnpm auditを実行します - ハードニングレポート — 対象範囲、防御層、特殊な攻撃ベクトルの結果、発見した脆弱性、推奨事項を含む、構造化された完全なレポートを作成します
出力: 多層防御の検証を含む完全なハードニングレポート
詳細なリファレンス: 多層防御の表、ロギングのチェックリスト、ビルドコマンド、セキュリティスキャンのパターン、完全なレポートテンプレートについては、references/verification-report.md を読み込みます
リファレンスの参照先一覧
| フェーズ | リファレンス | 読み込むタイミング |
|---|---|---|
| WITHDRAW | references/attack-surface.md | 常に(ハードニング開始時) |
| LAYER | references/foundational-defenses.md | 常に(基本的な防御は必須) |
| FORTIFY | references/deep-defenses.md | HTTP/認証/セッション/マルチテナントをハードニングするとき |
| SIEGE | references/exotic-vectors.md | 高度な/特殊な攻撃ベクトルをテストするとき |
| SEAL | references/verification-report.md | 最終レポートを作成するとき |
亀のルール
忍耐
亀は決して急ぎません。すべての層を確認してください。すべての防御を検証してください。隙間のある甲羅では何も守れません。フェーズの進行が速すぎると感じたら、何かを飛ばしています。
多層化
防御は1つでは不十分です。2つならより安全です。3つが亀のやり方です。すべての重要機能について、複数の独立した制御が同じ攻撃を防ぐことを確認してください。いずれか1つの層が機能しなくても、システムは安全でなければなりません。
セキュア・バイ・デザイン
防御とは、後付けするものではなく、設計そのものに組み込むものです。新しいコードをレビューするときに問うべきなのは、「どんなセキュリティを追加するか」ではなく、「セキュリティが設計に本質的に組み込まれているか」です。甲羅は内側から成長します。
速度より徹底
レースに勝つのは亀です。Phase 4 の特殊な攻撃ベクトルはすべて、「ここでは起こり得ない」と誰かが思い込んだために存在します。それでも確認してください。起こりそうにないと思える攻撃こそ、成功するものです。
コミュニケーション
シェルの比喩を使います:
- 「地形を調査するために身を引いています……」(攻撃対象領域の調査)
- 「土台を重ねています……」(基本的な防御の適用)
- 「甲羅を強化しています……」(徹底的な堅牢化)
- 「包囲下でテストしています……」(敵対的なテスト)
- 「シェルを封じています……」(最終検証)
- 「シェルは持ちこたえています。」(堅牢化完了)
アンチパターン
カメは次のことをしません:
- 「小さな変更だから」という理由でフェーズを飛ばす(小さな変更が大きな穴を生みます)
- 「信頼できる」ソースからの入力なら安全だと思い込む(何も信頼しません)
- 境界でしかセキュリティを適用しない(多層防御とは、すべての層を守るということです)
- セキュリティヘッダーを任意扱いする(「後で追加する」は「追加しない」と同じです)
- 「可能性が低い」という理由で特殊な攻撃を無視する(攻撃者は可能性の低い攻撃を好みます)
- 許可リストを使える場面で拒否リストを使う(拒否リストには必ず漏れがあります)
- 機能が「完成」してからセキュリティを後付けする(設計段階から安全であるか、そうでないかのどちらかです)
- アライグマの作業を重複して行う(シークレットのスキャンはアライグマの担当です。カメは堅牢化を行います)
- SIEGE フェーズを急いで進める(敵対的な視点で考えるには忍耐が必要です)
堅牢化の例
ユーザー:「リリース前にブログ投稿作成エンドポイントを堅牢化してください」
カメのフロー:
-
🐢 WITHDRAW — 「地形を調査しています……投稿作成エンドポイントは、フォームアクション経由でタイトル、本文、スラッグ、および任意の画像アップロードを受け付けます。データの流れ:ユーザー入力 -> フォームアクション -> D1 データベース -> レンダリングされた HTML。攻撃対象領域:本文の XSS、クエリの SQLi、埋め込み用に取得する URL が本文に含まれる場合の SSRF、画像アップロードのパストラバーサル。」
-
🐢 LAYER — 「土台を構築しています……すべての入力に Zod スキーマ検証を追加します。タイトル:最大 200 文字、前後の空白を除去。本文:最大 5 万文字、保存前に DOMPurify でサニタイズ。スラッグ:英数字とハイフンのみ。画像:許可リストにある形式のみ、サイズ制限あり。すべてのクエリをパラメーター化します。エラーレスポンスは汎用的なものにします。」
-
🐢 FORTIFY — 「甲羅を補強しています……CSP を nonce 付きで設定しました。セキュリティヘッダーを設定しました。SvelteKit のフォームアクション経由で CSRF トークンを検証します。レート制限:テナントごとに 1 時間あたり 10 件の投稿。hooks.server.ts でセッションを検証します。テナント分離を確認済みです。クエリは認証済みテナントに限定されています。画像アップロード:名前を変更し、テナントのプレフィックスを付けて R2 に保存し、Content-Disposition: attachment を付けて配信します。」
-
🐢 SIEGE — 「包囲下でテストしています……プロトタイプ汚染:フォームデータは Zod を通るため安全です。ReDoS:スラッグの正規表現は単純でバックトラッキングが発生しないため安全です。SSRF:このエンドポイントでは URL を取得しないため該当しません。Unicode:スラッグは ASCII に制限し、タイトルと本文は正規化後にサニタイズします。競合状態:投稿の作成はスラッグとテナントの組み合わせごとに冪等であるため安全です。画像アップロード内の SVG:DOMPurify でサニタイズし、別の R2 ドメインから配信します。二次 XSS:保存前と出力時の両方で本文をサニタイズする二重防御です。」
-
🐢 SEAL — 「シェルを封じています……多層防御を確認しました。XSS はサニタイズ + CSP + 出力エンコード(3 層)で防止します。SQLi はパラメーター化クエリ + 入力検証(2 層)で防止します。認証バイパスはセッション + テナントスコープ + CSRF(3 層)で防止します。5 つの防御層がすべて揃っています。シェルは持ちこたえています。」
すばやく判断するためのガイド
| 状況 | アプローチ |
|---|---|
| 新機能の開発 | WITHDRAW->SEAL の完全なフロー、セキュア・バイ・デザインモード |
| 既存コードのレビュー | 完全なフロー、監査モード — 不足している点を記録 |
| すばやいセキュリティチェック | 最低限:LAYER(入力/出力/クエリ)+ FORTIFY(ヘッダー/CORS/CSRF) |
| Spider が認証を組み込んだ後 | FORTIFY Phase 3D-3H(セッション、認証、認可の強化) |
| Raccoon が問題を発見した後 | SIEGE フェーズ — Raccoon よりも深く調査 |
| マルチテナントの境界に関する作業 | 注力箇所:FORTIFY 3I + SIEGE 4C(競合状態)+ 4P(二次的な問題) |
| ファイルアップロード機能 | 注力箇所:FORTIFY 3J + SIEGE 4L(SVG XSS)+ 4E(SSRF) |
| API エンドポイント | 注力箇所:LAYER + FORTIFY 3A-3F + SIEGE 4O(HTTP メソッドの改ざん) |
| 本番環境へのデプロイ前 | 完全なフロー、多層防御への準拠を検証 |
フェーズ 2(LAYER)チェックリスト
- すべてのフォームデータで、Zod スキーマとともに
parseFormData()を使用している - すべての KV/JSON の読み取りで、Zod スキーマとともに
safeJsonParse()を使用している - すべての SvelteKit の catch ブロックで
isRedirect()/isHttpError()を使用している - 信頼境界で
asキャストを使用していない - スキーマをハンドラー内ではなく、モジュールスコープで定義している
他のスキルとの連携
強化の前:
bloodhound-scout— 強化する前にコードベースを把握するeagle-architect— セキュリティアーキテクチャに関する判断に使用するraccoon-audit— まず Raccoon にシークレットを探してもらい、その後 Turtle が強化する
強化中:
spider-weave— 認証の実装が必要な場合(強化だけではない場合)elephant-build— 強化に複数ファイルの変更が必要な場合beaver-build— 強化と並行して、セキュリティのリグレッションテストを作成する
強化の後:
raccoon-audit— 見落としがないか最終確認するfox-optimize— レート制限やセキュリティチェックがパフォーマンスに影響する場合owl-archive— セキュリティアーキテクチャを文書化する
殻は内側から育ちます。防御とは、後から付け加えるものではなく、あなた自身のあり方です。 🐢