takt/builtins/ja/knowledge/security.md
nrslib ea7ce54912 takt: # タスク指示書: resources/ → builtins/ リネーム + export-cc 修正
## 概要
`resources/` ディレクトリを `builtins/` にリネームし、用途を明確化。同時に export-cc コマンドを拡張して全リソースをコピーするように修正する。

---

## タスク一覧

### 1. ディレクトリリネーム(優先度: 高)

| 変更前 | 変更後 |
|--------|--------|
| `resources/` | `builtins/` |
| `resources/global/{lang}/` | `builtins/{lang}/`(global/ 階層を除去) |
| `resources/project/` | `builtins/project/` |
| `resources/skill/` | `builtins/skill/` |

### 2. 不要ファイル削除(優先度: 高)

- `builtins/{lang}/prompts/` を削除
  - 対象: `interactive-system.md`, `interactive-summary.md`
  - 理由: コードから未参照、実体は `src/shared/prompts/`

### 3. コード修正 — パス参照(優先度: 高)

`resources` → `builtins`、`global/{lang}` → `{lang}` に更新:

| ファイル | 修正内容 |
|----------|----------|
| `src/infra/resources/index.ts` | `getResourcesDir()`, `getGlobalResourcesDir()`, `getLanguageResourcesDir()` 等のパス |
| `src/infra/config/paths.ts` | `getBuiltinPiecesDir()`, `getBuiltinPersonasDir()` |
| `src/infra/config/global/initialization.ts` | `copyLanguageConfigYaml()` |
| `src/infra/config/loaders/pieceCategories.ts` | `getLanguageResourcesDir()` 参照 |
| `src/features/config/ejectBuiltin.ts` | `getLanguageResourcesDir()` 参照 |
| `src/features/config/deploySkill.ts` | `getResourcesDir()` 参照 |

### 4. export-cc 修正(優先度: 高)

ファイル: `src/features/config/deploySkill.ts`

**現状**: pieces/ と personas/ のみコピー

**修正後**:
- `builtins/{lang}/` 全体を `~/.claude/skills/takt/` にコピー
- `skill/` のファイル(SKILL.md, references/, takt-command.md)は従来通り
- サマリー表示を新リソースタイプ(stances, instructions, knowledge 等)に対応
- confirm メッセージ修正:
  - 現状: `'上書きしますか?'`
  - 修正後: `'既存のスキルファイルをすべて削除し、最新版に置き換えます。続行しますか?'`

### 5. テスト修正(優先度: 中)

| ファイル | 修正内容 |
|----------|----------|
| `src/__tests__/initialization.test.ts` | `getLanguageResourcesDir` のパス期待値 |
| `src/__tests__/piece-category-config.test.ts` | mock パス |
| その他 `resources` パスを参照しているテスト | パス更新 |

### 6. ビルド・パッケージ設定(優先度: 中)

| ファイル | 修正内容 |
|----------|----------|
| `package.json` | `files` フィールドで `resources/` → `builtins/` |
| `tsconfig.json` | `resources/` への参照があれば更新 |
| `.gitignore` | 必要に応じて更新 |

### 7. ドキュメント(優先度: 低)

- `CLAUDE.md` の Directory Structure セクションを更新
- JSDoc コメントから `prompts/` 記述を削除

---

## 制約

- `builtins/{lang}/` のフラット構造は変更不可(ピースYAML内の相対パス依存)
- eject のセーフティ(skip-if-exists)は変更不要
- export-cc のセーフティ(SKILL.md 存在チェック + confirm)は維持

---

## 確認方法

- `npm run build` が成功すること
- `npm test` が全てパスすること
- `takt init` / `takt eject` / `takt export-cc` が正常動作すること
2026-02-07 14:46:20 +09:00

5.1 KiB
Raw Blame History

セキュリティ知識

AI生成コードのセキュリティ問題

AI生成コードには特有の脆弱性パターンがある。

パターン リスク
もっともらしいが危険なデフォルト cors: { origin: '*' } は問題なく見えるが危険
古いセキュリティプラクティス 非推奨の暗号化、古い認証パターンの使用
不完全なバリデーション 形式は検証するがビジネスルールを検証しない
入力を過度に信頼 重大 内部APIは常に安全と仮定
コピペによる脆弱性 同じ危険なパターンが複数ファイルで繰り返される

特に厳しく審査が必要:

  • 認証・認可ロジックAIはエッジケースを見落としがち
  • 入力バリデーションAIは構文を検証しても意味を見落とす可能性
  • エラーメッセージAIは内部詳細を露出する可能性
  • 設定ファイルAIは学習データから危険なデフォルトを使う可能性

インジェクション攻撃

SQLインジェクション

  • 文字列連結によるSQL構築 → REJECT
  • パラメータ化クエリの不使用 → REJECT
  • ORMの raw query での未サニタイズ入力 → REJECT
// NG
db.query(`SELECT * FROM users WHERE id = ${userId}`)

// OK
db.query('SELECT * FROM users WHERE id = ?', [userId])

コマンドインジェクション

  • exec(), spawn() での未検証入力 → REJECT
  • シェルコマンド構築時のエスケープ不足 → REJECT
// NG
exec(`ls ${userInput}`)

// OK
execFile('ls', [sanitizedInput])

XSS (Cross-Site Scripting)

  • HTML/JSへの未エスケープ出力 → REJECT
  • innerHTML, dangerouslySetInnerHTML の不適切な使用 → REJECT
  • URLパラメータの直接埋め込み → REJECT

認証・認可

認証の問題

  • ハードコードされたクレデンシャル → 即REJECT
  • 平文パスワードの保存 → 即REJECT
  • 弱いハッシュアルゴリズム (MD5, SHA1) → REJECT
  • セッショントークンの不適切な管理 → REJECT

認可の問題

  • 権限チェックの欠如 → REJECT
  • IDOR (Insecure Direct Object Reference) → REJECT
  • 権限昇格の可能性 → REJECT
// NG - 権限チェックなし
app.get('/user/:id', (req, res) => {
  return db.getUser(req.params.id)
})

// OK
app.get('/user/:id', authorize('read:user'), (req, res) => {
  if (req.user.id !== req.params.id && !req.user.isAdmin) {
    return res.status(403).send('Forbidden')
  }
  return db.getUser(req.params.id)
})

データ保護

機密情報の露出

  • APIキー、シークレットのハードコーディング → 即REJECT
  • ログへの機密情報出力 → REJECT
  • エラーメッセージでの内部情報露出 → REJECT
  • .env ファイルのコミット → REJECT

データ検証

  • 入力値の未検証 → REJECT
  • 型チェックの欠如 → REJECT
  • サイズ制限の未設定 → REJECT

暗号化

  • 弱い暗号アルゴリズムの使用 → REJECT
  • 固定IV/Nonceの使用 → REJECT
  • 暗号化キーのハードコーディング → 即REJECT
  • HTTPSの未使用本番環境 → REJECT

ファイル操作

パストラバーサル

  • ユーザー入力を含むファイルパス → REJECT
  • ../ のサニタイズ不足 → REJECT
// NG
const filePath = path.join(baseDir, userInput)
fs.readFile(filePath)

// OK
const safePath = path.resolve(baseDir, userInput)
if (!safePath.startsWith(path.resolve(baseDir))) {
  throw new Error('Invalid path')
}

ファイルアップロード

  • ファイルタイプの未検証 → REJECT
  • ファイルサイズ制限なし → REJECT
  • 実行可能ファイルのアップロード許可 → REJECT

依存関係

  • 既知の脆弱性を持つパッケージ → REJECT
  • メンテナンスされていないパッケージ → 警告
  • 不必要な依存関係 → 警告

エラーハンドリング

  • スタックトレースの本番露出 → REJECT
  • 詳細なエラーメッセージの露出 → REJECT
  • エラーの握りつぶし(セキュリティイベント) → REJECT

レート制限・DoS対策

  • レート制限の欠如(認証エンドポイント) → 警告
  • リソース枯渇攻撃の可能性 → 警告
  • 無限ループの可能性 → REJECT

OWASP Top 10 チェックリスト

カテゴリ 確認事項
A01 Broken Access Control 認可チェック、CORS設定
A02 Cryptographic Failures 暗号化、機密データ保護
A03 Injection SQL, コマンド, XSS
A04 Insecure Design セキュリティ設計パターン
A05 Security Misconfiguration デフォルト設定、不要な機能
A06 Vulnerable Components 依存関係の脆弱性
A07 Auth Failures 認証メカニズム
A08 Software Integrity コード署名、CI/CD
A09 Logging Failures セキュリティログ
A10 SSRF サーバーサイドリクエスト