mcpField
S
sharp-edges

sharp-edges

github.com/waybarriosセキュリティ54644 回インストール1 日前に更新
リポジトリ

sharp-edges について

sharp-edgesは、API、設定、インターフェースが安全に使いやすいかを評価するセキュリティレビュー用スキルです。安全でないデフォルト、型の混同、エラーの隠蔽などの誤用リスクに着目し、体系的な検証手順を示します。

主な機能

  1. 01APIと設定の誤用リスクをレビュー
  2. 02危険なデフォルトと設定上の落とし穴を特定
  3. 03境界値と失敗経路を調査
  4. 04誤用例で指摘事項を検証
  5. 05重大度分類と品質チェックリスト

活用シーン

  1. 01暗号APIの開発者向け設計をレビュー
  2. 02認証・認可インターフェースを評価
  3. 03設定項目の危険な組み合わせを監査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/waybarrios/opencode-power-pack --skill sharp-edges

インストール後、Claude Code で/sharp-edgesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
auth-patterns.md
case-studies.md
config-patterns.md
crypto-apis.md
lang-c.md
lang-csharp.md
lang-go.md
lang-java.md
lang-javascript.md
lang-kotlin.md
lang-php.md
lang-python.md
lang-ruby.md
lang-rust.md
lang-swift.md
language-specific.md

詳細

鋭いエッジの分析

API、設定、インターフェースが、開発者による誤用にどれだけ強いかを評価します。「簡単な方法」を選ぶと安全性が損なわれる設計を特定します。

使用する場面

  • API やライブラリの設計上の判断をレビューする
  • 危険なオプションがないか設定スキーマを監査する
  • 暗号 API の使いやすさを評価する
  • 認証・認可インターフェースを評価する
  • セキュリティに関わる選択肢を開発者に公開するコードをレビューする

使用しない場面

  • 実装上のバグ(通常のコードレビューを使用)
  • ビジネスロジックの欠陥(ドメイン固有の分析を使用)
  • パフォーマンスの最適化(別の観点)

基本原則

成功への道筋:安全な使い方が、最も抵抗の少ない道であるべきです。脆弱性を避けるために、開発者が暗号技術を理解したり、ドキュメントを注意深く読んだり、特別なルールを覚えたりしなければならないなら、その API は失敗です。

退けるべき合理化

合理化それが誤りである理由必須の対応
「ドキュメントに書いてあります」開発者は締め切りに追われているとき、ドキュメントを読みません安全な選択肢をデフォルト、または唯一の選択肢にする
「上級者には柔軟性が必要です」柔軟性は誤用の落とし穴を生みます。「上級者向け」の使い方の大半はコピー&ペーストです安全な高水準 API を提供し、プリミティブを隠す
「開発者の責任です」責任転嫁です。落とし穴を設計したのはあなたです落とし穴をなくすか、誤用を不可能にする
「実際にそんなことをする人はいません」開発者はプレッシャーのもとで、想像しうるあらゆることをします開発者が最大限に混乱することを前提にする
「ただの設定オプションです」設定もコードです。誤った設定が本番環境に適用されます設定を検証し、危険な組み合わせを拒否する
「後方互換性が必要です」安全でないデフォルトに既得権を認めることはできません明確に非推奨化し、移行を必須にする

鋭いエッジのカテゴリ

1. アルゴリズム/モード選択の落とし穴

開発者にアルゴリズムを選ばせる API は、誤った選択を招きます。

JWT パターン(典型例):

  • ヘッダーでアルゴリズムを指定する:攻撃者が "alg": "none" を設定して署名を回避できる
  • アルゴリズムの混同:RS256 から HS256 に切り替える際、RSA 公開鍵が HMAC のシークレットとして使われる
  • 根本原因:信頼できない入力に、セキュリティ上重要な判断を制御させている

検出パターン:

  • algorithm、mode、cipher、hash_type などの関数パラメーター
  • 暗号プリミティブを選択する列挙型や文字列
  • セキュリティ機構の設定オプション

例 - 弱いアルゴリズムを許可する PHP の password_hash:

// DANGEROUS: allows crc32, md5, sha1
password_hash($password, PASSWORD_DEFAULT); // Good - no choice
hash($algorithm, $password); // BAD: accepts "crc32"
2. 危険なデフォルト

安全でないデフォルトや、セキュリティを無効にするゼロ値/空値です。

OTP の有効期間パターン:

# What happens when lifetime=0?
def verify_otp(code, lifetime=300):  # 300 seconds default
    if lifetime == 0:
        return True  # OOPS: 0 means "accept all"?
        # Or does it mean "expired immediately"?

検出パターン:

  • 0 を受け入れるタイムアウト/有効期間(無期限? 即時失効?)
  • チェックを回避する空文字列
  • 検証をスキップする null 値
  • セキュリティ機能を無効にするブール値のデフォルト
  • 意味が未定義の負の値

確認すべき質問:

  • timeout=0、max_attempts=0、key="" の場合、何が起きますか?
  • デフォルトは最も安全な選択肢ですか?
  • デフォルト値によってセキュリティを完全に無効にできますか?
3. プリミティブ API と意味的 API

意味のある型ではなく生のバイト列を公開する API は、型の混同を招きます。

Libsodium と Halite のパターン:

// Libsodium (primitives): bytes are bytes
sodium_crypto_box($message, $nonce, $keypair);
// Easy to: swap nonce/keypair, reuse nonces, use wrong key type

// Halite (semantic): types enforce correct usage
Crypto::seal($message, new EncryptionPublicKey($key));
// Wrong key type = type error, not silent failure

検出パターン:

  • セキュリティ上異なる概念に対して bytes、string、[]byte を受け取る関数
  • 型エラーなしで入れ替えられるパラメーター
  • 鍵、ノンス、暗号文、署名に同じ型を使用する

比較の落とし穴:

// Timing-safe comparison looks identical to unsafe
if hmac == expected { }           // BAD: timing attack
if hmac.Equal(mac, expected) { }  // Good: constant-time
// Same types, different security properties
4. 設定の落とし穴

設定を1つ誤るだけで、警告もなく致命的な障害が発生します。

検出パターン:

  • セキュリティを完全に無効化するブール値フラグ
  • 検証されない文字列設定
  • 危険な相互作用を引き起こす設定の組み合わせ
  • セキュリティ設定を上書きする環境変数
  • 適切なデフォルト値があるものの検証されないコンストラクターのパラメーター(呼び出し元が安全でない値で上書きできる)

例:

# One typo = disaster
verify_ssl: fasle  # Typo silently accepted as truthy?

# Magic values
session_timeout: -1  # Does this mean "never expire"?

# Dangerous combinations accepted silently
auth_required: true
bypass_auth_for_health_checks: true
health_check_path: "/"  # Oops
// Sensible default doesn't protect against bad callers
public function __construct(
    public string $hashAlgo = 'sha256',  // Good default...
    public int $otpLifetime = 120,       // ...but accepts md5, 0, etc.
) {}

詳しいパターンについては、config-patterns.md を参照してください。

5. サイレントな障害

エラーが表面化しなかったり、成功が障害を覆い隠したりします。

検出パターン:

  • セキュリティ上の失敗時に例外をスローせず、ブール値を返す関数
  • セキュリティ処理を囲む空の catch ブロック
  • 解析エラー時に代替されるデフォルト値
  • 不正な入力でも「成功」する検証関数

例:

# Silent bypass
def verify_signature(sig, data, key):
    if not key:
        return True  # No key = skip verification?!

# Return value ignored
signature.verify(data, sig)  # Throws on failure
crypto.verify(data, sig)     # Returns False on failure
# Developer forgets to check return value
6. 文字列で表現されたセキュリティ値

セキュリティ上重要な値を通常の文字列で扱うと、インジェクションや混乱を招きます。

検出パターン:

  • 文字列連結で構築される SQL/コマンド
  • カンマ区切りの文字列で表現される権限
  • 列挙型ではなく任意の文字列で表現されるロール/スコープ
  • 文字列を連結して構築される URL

権限の蓄積に潜む落とし穴:

permissions = "read,write"
permissions += ",admin"  # Too easy to escalate

# vs. type-safe
permissions = {Permission.READ, Permission.WRITE}
permissions.add(Permission.ADMIN)  # At least it's explicit

分析ワークフロー

フェーズ 1:対象の特定
  1. セキュリティ関連 API をマッピングする:認証、認可、暗号化、セッション管理、入力検証
  2. 開発者が選択するポイントを特定する:開発者はアルゴリズムを選択したり、タイムアウトを設定したり、モードを選んだりできますか?
  3. 設定スキーマを見つける:環境変数、設定ファイル、コンストラクターのパラメーター
フェーズ 2:エッジケースの調査

各選択ポイントについて、次の点を確認します:

  • ゼロ/空/null:0、""、null、[] の場合、どうなりますか?
  • 負の値:-1 は何を意味しますか?無限ですか?エラーですか?
  • 型の混同:異なるセキュリティ概念を入れ替えられますか?
  • デフォルト値:デフォルト値は安全ですか?文書化されていますか?
  • エラー処理:無効な入力の場合、どうなりますか?黙って受け入れられますか?
フェーズ 3:脅威モデリング

3 種類の敵対者を考慮します:

  1. 悪意ある開発者:設定を制御する、積極的に悪意のある開発者または攻撃者

    • 設定によってセキュリティを無効化できますか?
    • アルゴリズムをダウングレードできますか?
    • 悪意のある値を注入できますか?
  2. 怠惰な開発者:サンプルをコピー&ペーストし、ドキュメントを読み飛ばす開発者

    • 最初に見つけるサンプルは安全ですか?
    • 最も手軽な方法は安全ですか?
    • エラーメッセージは安全な使い方へ導きますか?
  3. 混乱している開発者:API を誤解している開発者

    • 型エラーなしでパラメーターを入れ替えられますか?
    • 誤って間違った鍵/アルゴリズム/モードを使えますか?
    • 失敗の状態は明らかですか、それとも気づかれないままですか?
フェーズ 4:調査結果の検証

特定した各落とし穴について:

  1. 誤用を再現する:落とし穴を実証する最小限のコードを書く
  2. 悪用可能性を確認する:誤用によって実際の脆弱性が生じますか?
  3. ドキュメントを確認する:危険性は文書化されていますか?(ドキュメントが設計の悪さを正当化するわけではありませんが、深刻度には影響します)
  4. 緩和策をテストする:妥当な労力で API を安全に使用できますか?

調査結果に疑問がある場合は、フェーズ 2 に戻ってさらにエッジケースを調べます。

深刻度の分類

深刻度基準例
致命的デフォルトの使用方法、または明白な使用方法が安全でないverify: false がデフォルト;空のパスワードが許可される
高簡単な設定ミスでセキュリティが損なわれるアルゴリズムのパラメーターが "none" を受け入れる
中まれだが起こり得る設定ミス負のタイムアウト値が予期しない意味を持つ
低意図的な誤用が必要わかりにくいパラメーターの組み合わせ

参考資料

カテゴリ別:

言語別(暗号固有ではない、一般的な落とし穴):

言語ガイド
C/C++references/lang-c.md
Goreferences/lang-go.md
Rustreferences/lang-rust.md
Swiftreferences/lang-swift.md
Javareferences/lang-java.md
Kotlinreferences/lang-kotlin.md
C#references/lang-csharp.md
PHPreferences/lang-php.md
JavaScript/TypeScriptreferences/lang-javascript.md
Pythonreferences/lang-python.md
Rubyreferences/lang-ruby.md

まとめたクイックリファレンスについては、references/language-specific.md も参照してください。

品質チェックリスト

分析を終える前に:

  • ゼロ/空/null のすべてのエッジケースを調査した
  • デフォルトが安全であることを確認した
  • アルゴリズム/モード選択に関する落とし穴を確認した
  • セキュリティ上の概念間で型が混同されないかテストした
  • 3 種類すべての敵対者を考慮した
  • エラー経路がセキュリティを迂回しないことを確認した
  • 設定の検証を確認した
  • コンストラクターのパラメーターを検証した(デフォルト値を設定するだけでなく)。config-patterns.md を参照してください

コメント