insecure-defaults について
アプリケーションや設定の安全でないデフォルトを監査する、防御目的のセキュリティスキルです。認証情報の露出、フェイルオープン、弱い暗号、過度に許容的な設定を調べ、重要度と修正案を示します。
主な機能
- 01ハードコード認証情報の検出
- 02デフォルトパスワードの確認
- 03フェイルオープンの分析
- 04安全でない設定の検査
- 05重要度別の検出結果と修正案
活用シーン
- 01自社アプリケーションの監査
- 02デプロイ前の設定確認
- 03セキュリティコンプライアンスの検証
- 04サードパーティコンポーネントのレビュー
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill insecure-defaultsインストール後、Claude Code で/insecure-defaultsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
commands/insecure-defaults.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/insecure-defaults.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md詳細
安全でないデフォルト設定
セキュリティに関する注意
許可された用途のみ:これらのスキルは、防御的なセキュリティ分析と許可された調査を目的としています。
- 所有するアプリケーションの設定監査
- CI/CD パイプラインにおけるデプロイ前のセキュリティチェック
- コンプライアンス検証(SOC2、PCI-DSS、HIPAA)
- サードパーティコンポーネントのセキュリティ評価
- 管理された環境での教育目的
次の目的には絶対に使用しないでください:
- 許可なく、発見した認証情報を悪用する
- 発見したデフォルトパスワードを使ってシステムにアクセスする
- セキュリティ制御を回避する
- あらゆる違法行為
ステップ 1:認証情報の検出
ハードコードされた認証情報のパターン
ソースコードに直接埋め込まれた認証情報を検索します。
# Password patterns
grep -rnE "(password|passwd|pwd)\s*[=:]\s*['\"][^'\"]{3,}" --include="*.{js,ts,py,java,go,rb,php}" .
# API key patterns
grep -rnE "(api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['\"][^'\"]{8,}" --include="*.{js,ts,py,java,go}" .
# Token patterns
grep -rnE "(token|secret|auth)\s*[=:]\s*['\"][A-Za-z0-9+/=]{16,}" --include="*.{js,ts,py,java,go}" .
# AWS credentials
grep -rnE "AKIA[0-9A-Z]{16}" .
grep -rnE "aws_secret_access_key\s*[=:]\s*['\"][^'\"]{20,}" .
# Private keys
grep -rnl "BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY" .
# Connection strings with embedded credentials
grep -rnE "(mysql|postgres|mongodb|redis)://[^:]+:[^@]+@" --include="*.{js,ts,py,java,go,yml,yaml,json,env}" .
認証情報検出のための Semgrep ルール
rules:
- id: hardcoded-password
message: >
Hardcoded password detected. Store passwords in environment
variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault).
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-798]
owasp: [A07:2021]
confidence: HIGH
impact: HIGH
category: security
patterns:
- pattern-either:
- pattern: |
$VAR = "..."
- pattern: |
const $VAR = "..."
- pattern: |
let $VAR = "..."
- metavariable-regex:
metavariable: $VAR
regex: (?i)(password|passwd|pwd|secret|credential|api.?key)
- pattern-not: |
$VAR = ""
- pattern-not: |
$VAR = "changeme"
- pattern-not: |
$VAR = "placeholder"
- id: hardcoded-password-in-config
message: >
Password found in configuration file. Use environment variable
references or encrypted secrets instead.
severity: ERROR
languages: [json, yaml]
metadata:
cwe: [CWE-798]
owasp: [A07:2021]
confidence: MEDIUM
impact: HIGH
category: security
pattern-regex: (?i)(password|secret|api.?key|token)\s*[:=]\s*["']?[a-zA-Z0-9+/=!@#$%^&*]{8,}
ステップ 2:フェイルオープンの検出
フェイルオープンとは
フェイルオープンとは、エラー処理時に「アクセスを拒否」せず、デフォルトでアクセスを許可することです。これは「フェイルセキュア」の原則とは逆の動作です。
フェイルオープンのパターン
// FAIL-OPEN: Error in auth check grants access
try {
const isAuthorized = await checkAuth(req);
if (!isAuthorized) return res.status(403).send('Forbidden');
} catch (err) {
// BUG: Error falls through, request proceeds without auth
console.log('Auth error:', err);
}
// ... handler continues, even on auth error
// FAIL-SECURE: Error in auth check denies access
try {
const isAuthorized = await checkAuth(req);
if (!isAuthorized) return res.status(403).send('Forbidden');
} catch (err) {
console.error('Auth error:', err);
return res.status(500).send('Internal error'); // DENY on error
}
フェイルオープンを検出する Semgrep ルール
rules:
- id: fail-open-auth-catch
message: >
Authentication/authorization error is caught but execution continues.
This is a fail-open pattern. Ensure errors in auth checks result
in access denial, not access grant.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-636]
owasp: [A07:2021]
confidence: MEDIUM
impact: HIGH
category: security
patterns:
- pattern: |
try {
...
$AUTH(...)
...
} catch ($ERR) {
...
}
...
$RESPONSE(...)
- metavariable-regex:
metavariable: $AUTH
regex: (?i)(auth|authenticate|authorize|checkPermission|verifyToken|validateSession)
- pattern-not-inside: |
try { ... } catch ($ERR) { ... return ...; }
- pattern-not-inside: |
try { ... } catch ($ERR) { ... throw ...; }
- id: fail-open-empty-catch
message: >
Empty catch block silently swallows errors. This can cause
fail-open behavior if the try block contains security checks.
severity: WARNING
languages: [javascript, typescript]
metadata:
cwe: [CWE-390]
confidence: MEDIUM
impact: MEDIUM
category: security
pattern: |
try { ... } catch ($ERR) { }
ステップ 3:安全でない設定の検出
よくある安全でないデフォルト設定
| カテゴリ | 安全でないデフォルト設定 | 安全な代替設定 |
|---|---|---|
| CORS | origin: '*' | 許可するオリジンを明示 |
| デバッグ | 本番環境で debug: true | debug: false |
| バインド | 0.0.0.0(すべてのインターフェース) | 127.0.0.1 または特定の IP |
| TLS | rejectUnauthorized: false | rejectUnauthorized: true |
| Cookie | secure: false、httpOnly: false | secure: true、httpOnly: true |
| セッション | secret: 'keyboard cat' | 環境変数から取得したランダムなシークレット |
| 暗号化 | MD5、SHA1、DES、RC4 | SHA-256 以上、AES-256、ChaCha20 |
| 権限 | 0777 のファイル権限 | 0644 または 0600 |
| JWT | algorithm: 'none' | algorithm: 'RS256' または 'ES256' |
| レート制限 | レート制限なし | レート制限を有効化 |
| CSRF | CSRF 保護が無効 | CSRF 保護を有効化 |
| Helmet | セキュリティヘッダーなし | Helmet ミドルウェアを有効化 |
安全でない設定を検出する Semgrep ルール
rules:
- id: cors-wildcard-origin
message: >
CORS allows all origins ('*'). This permits any website to make
cross-origin requests. Specify allowed origins explicitly.
severity: WARNING
languages: [javascript, typescript]
metadata:
cwe: [CWE-942]
owasp: [A05:2021]
confidence: HIGH
impact: MEDIUM
category: security
pattern-either:
- pattern: cors({ origin: '*' })
- pattern: cors({ origin: true })
- pattern: |
$RES.setHeader("Access-Control-Allow-Origin", "*")
- id: tls-verification-disabled
message: >
TLS certificate verification is disabled. This allows
man-in-the-middle attacks. Remove rejectUnauthorized: false.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-295]
owasp: [A02:2021]
confidence: HIGH
impact: HIGH
category: security
pattern-either:
- pattern: rejectUnauthorized: false
- pattern: process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
- pattern: process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'
- id: debug-mode-enabled
message: >
Debug mode appears to be enabled. Ensure debug mode is
disabled in production to prevent information disclosure.
severity: WARNING
languages: [javascript, typescript, python]
metadata:
cwe: [CWE-489]
owasp: [A05:2021]
confidence: MEDIUM
impact: MEDIUM
category: security
pattern-either:
- pattern: "DEBUG = True"
- pattern: "debug: true"
- pattern: app.debug = true
- id: weak-crypto-algorithm
message: >
Weak cryptographic algorithm detected. Use SHA-256 or stronger
for hashing, AES-256 for encryption.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-327]
owasp: [A02:2021]
confidence: HIGH
impact: HIGH
category: security
patterns:
- pattern: crypto.createHash($ALGO)
- metavariable-regex:
metavariable: $ALGO
regex: ['"]?(md5|sha1|md4|md2|ripemd)['"]?
ステップ 4:環境変数と設定ファイルのスキャン
確認するファイル
# Environment files
find . -name "*.env*" -not -path "*/node_modules/*"
find . -name ".env.example" -o -name ".env.sample"
# Configuration files
find . -name "config.*" -o -name "settings.*" -o -name "application.*" \
| grep -E "\.(js|ts|json|yaml|yml|toml|ini|cfg)$"
# Docker configurations
find . -name "Dockerfile*" -o -name "docker-compose*"
# Cloud configurations
find . -name "*.tf" -o -name "*.tfvars" \
-o -name "serverless.*" -o -name "*.cloudformation.*"
設定監査チェックリスト
## Configuration Security Audit
### Credentials
- [ ] No hardcoded passwords in source code
- [ ] No API keys in source code
- [ ] No private keys committed
- [ ] No database credentials in config files
- [ ] .env files are in .gitignore
- [ ] .env.example has placeholder values only
### Network
- [ ] Not binding to 0.0.0.0 in production
- [ ] TLS/SSL enabled for all connections
- [ ] Certificate verification enabled
- [ ] CORS restricted to known origins
### Authentication
- [ ] Session secret is random and from env var
- [ ] JWT algorithm is not 'none'
- [ ] Password hashing uses bcrypt/argon2 (not MD5/SHA1)
- [ ] Cookie settings: secure, httpOnly, sameSite
### Error Handling
- [ ] Auth errors deny access (fail-secure)
- [ ] No empty catch blocks in security paths
- [ ] Stack traces not exposed in production
- [ ] Default error handler returns 500, not 200
### Infrastructure
- [ ] Debug mode disabled in production
- [ ] File permissions are restrictive
- [ ] Default admin accounts disabled/changed
- [ ] Rate limiting enabled
- [ ] Security headers configured (Helmet/equivalent)
ステップ 5:レポート
安全でないデフォルト設定のレポート
## Insecure Defaults Assessment
**Date**: YYYY-MM-DD
**Scope**: [project/repository]
### Summary
| Category | Findings | Critical | High | Medium | Low |
| --------------------- | -------- | -------- | ----- | ------ | ----- |
| Hardcoded credentials | X | X | X | X | X |
| Fail-open patterns | X | X | X | X | X |
| Insecure config | X | X | X | X | X |
| Weak crypto | X | X | X | X | X |
| **Total** | **X** | **X** | **X** | **X** | **X** |
### Critical Findings
[Detailed findings with remediation]
### Recommended Secure Defaults
[Project-specific secure configuration template]
## デフォルト認証情報データベース
デフォルト認証情報を監査する際は、既知のデフォルト値と照合してください。
| 製品/サービス | デフォルトのユーザー名 | デフォルトのパスワード |
|---|---|---|
| PostgreSQL | postgres | postgres |
| MySQL | root | (空) |
| MongoDB | (なし) | (なし - 認証なし) |
| Redis | (なし) | (なし - 認証なし) |
| RabbitMQ | guest | guest |
| Elasticsearch | elastic | changeme |
| Jenkins | admin | (初期セットアップ時に設定) |
| Grafana | admin | admin |
ルール:アプリケーションにこれらのデフォルト値が含まれている場合は、CRITICAL として報告してください。
関連スキル
static-analysis- CodeQL と Semgrep によるスキャンvariant-analysis- 安全でないパターンの類似例の検出semgrep-rule-creator- カスタム検出ルールdifferential-review- 差分に含まれる新たな安全でないデフォルト値の検出security-architect- STRIDE 脅威モデリングauth-security-expert- 認証のベストプラクティス
エージェントとの連携
- security-architect(主要):セキュリティ設定の評価
- code-reviewer(主要):PR 内の設定レビュー
- penetration-tester(副次):認証情報の検証
- devops(副次):インフラストラクチャ設定の監査
絶対遵守事項
- 必ず、ハードコードされた認証情報やトークンは、どのような状況であっても CRITICAL の検出事項として扱ってください。「テスト用」や「サンプル用」の認証情報は本番環境にコピーされることがよくあるため、直ちに修正する必要があります。
- 決して、一時的であっても
rejectUnauthorized: falseや同等の TLS バイパスを使用しないでください。「一時的に」無効化した TLS 検証が本番環境にそのまま残ることはよくあります。安全な例外はありません。 - 必ず、ソースコードに加えて設定ファイル(
.env、YAML、JSON、TOML)もスキャンしてください。認証情報はアプリケーションコードより設定ファイルに埋め込まれていることのほうが多いためです。 - 自動スキャンツール(Semgrep、Trufflehog、git-secrets)を実行せずに、「検出事項なし」と報告してはなりません。手動レビューだけでは、エンコードされた認証情報や難読化された認証情報を見落とします。
- 必ず、セキュリティチェックがデフォルトでフェイルセキュア(アクセスを拒否)になっていることを確認してください。フェイルオープン設定(認証エラー時にアクセスを許可する設定)は、最も危険な種類の安全でないデフォルト設定です。
アンチパターン
| アンチパターン | 失敗する理由 | 適切なアプローチ |
|---|---|---|
| 「サンプル」認証情報を低重大度として扱う | サンプル値は本番環境にコピー&ペーストされます。JIRA/Slackには、本物の本番環境のシークレットが「一時的に」含まれています | ハードコードされた認証情報はすべて重大として検出し、Gitの履歴にある場合は直ちにローテーションします |
| 手動のみの認証情報スキャン | 人の目では、Base64エンコードされたシークレット、複数行のキー、ローテーションによって検出しにくくなったパターンを見落とします | すべてのコミットでTrufflehog + Semgrep + git-secretsを実行します。手動レビューは補完として行い、決して置き換えません |
テストコードでの rejectUnauthorized: false | テスト設定がコピー&ペーストによって本番環境に漏れます。TLSのバイパスはランタイム監視では検出できません | カスタムCAには NODE_EXTRA_CA_CERTS を使用し、ピア検証は決して無効にしません |
| 設定ファイルを確認しない | 認証情報の漏えいの60%以上は、ソースコードではなく設定ファイルに起因します | .env、*.yaml、*.json、*.toml、docker-compose.ymlを明示的にスキャンします |
| フレームワークのデフォルト設定が安全だと想定する | Flaskのdebug=True、DjangoのDEBUG=True、Spring Bootのアクチュエーターなど、フレームワークのデフォルト設定は開発者向けに最適化されており、本番環境で安全とは限りません | フレームワーク固有の安全でないデフォルト設定を列挙し、それぞれを本番環境向けに検証します |
メモリープロトコル(必須)
開始前:
.claude/context/memory/learnings.mdを読みます
完了後:
- 新しいパターン →
.claude/context/memory/learnings.md - 発見した問題 →
.claude/context/memory/issues.md - 決定事項 →
.claude/context/memory/decisions.md
中断されることを前提としてください。メモリーに記録されていないことは、起きていないことと同じです。
コメント
Markdown 対応