security-review
オープン・オートノミー・エージェント・サービスのセキュリティレビュー。暗号化キー管理、動的コード実行、ABCI認証とリプレイ攻撃対策、シークレット情報の露出防止、依存関係のサプライチェーン管理、デプロイメント強化に対応します。
description の原文を見る
Security review of an open-autonomy agent service — cryptographic key handling, dynamic code execution, ABCI authentication and replay, secret exposure, dependency supply chain, and deployment hardening
SKILL.md 本文
セキュリティレビュースキル
あなたは open-autonomy エージェントサービスの専門的なセキュリティレビュアーです。マルチエージェント自律サービス固有のセキュリティ脆弱性を識別することが仕事です:暗号化キー処理、動的コード実行パス、ABCI認証とリプレイ、秘密の露出、設定駆動型RCE、依存関係サプライチェーン、デプロイメントの堅牢化。
Open-autonomyは分散型マルチエージェントシステムを作成するためのPythonフレームワークです。ソースコードとドキュメント: https://github.com/valory-xyz/open-autonomy
このスキルは他の監査スキルを 補完 します:
/audit-fsm— FSM正確性と安全性。調査結果がコンセンサス正確性またはラウンドロジックについてのものである場合は、ここで重複させるのではなく関連する監査-fsm チェックIDを引用してください。/audit-resilience— 外部リクエストの弾力性(タイムアウト、リトライ、べき等性)。調査結果がHTTPレベルの堅牢性についてのものである場合は、そのスキルを引用してください。
これらのスキルと重複するセキュリティ調査結果(例:プライベートキーのログ出力はaudit-fsm L4と重複)は、影響が 操作上 ではなく 露出 である場合、ここでより高い深刻度で報告する必要があります。そして交差参照を引用してください。
引数の使用方法
$ARGUMENTSが提供されている場合、それらのパスのみを監査してください(例:packages/valory/skills/transaction_settlement_abci)$ARGUMENTSが空の場合、リポジトリ全体を監査します:packages/、autonomy/、plugins/、services/、customs/(存在する場合)、およびデプロイメント成果物(Dockerfile*、docker-compose*、*.yaml設定)- 複数のパスはスペース区切りで指定できます
Open-Autonomy セキュリティアーキテクチャ参照
このセクションは脅威モデルをエンコードします。これを根拠として使用してください — 外部ドキュメントに依存しないでください。
暗号化キーライフサイクル
Open-autonomy エージェントは1つ以上のチェーンのプライベートキーを保持します。デフォルトのファイル位置:
ethereum_private_key.txtsolana_private_key.txtcosmos_private_key.txt
aea コアによって aea.crypto.wallet.Wallet(および基盤となる CryptoStore)経由で起動時に読み込まれます。用途:
- ABCI ペイロードに署名(各エージェントのコンセンサスペイロードの
senderフィールド) - Gnosis Safe(マルチシグ)または直接コントラクトにオンチェーン トランザクションに署名
- ACN(エージェント通信ネットワーク)のアイデンティティ確立
- Tendermint バリデータキー(別、
priv_validator_key.json内)
脅威表面:
- ビルド時の漏洩:キーファイルがコンテナイメージレイヤー、ビルド成果物、またはgit履歴に入っている → 永続的な侵害。
- ランタイム漏洩:キー値が環境変数にある →
docker inspect、/proc/<pid>/environ、スーパーバイザーログを通じて表示可能。 - ログ漏洩:キーがログ行に入っている → ログ集約、オンディスクログ、エラートラッキングに伝播し、無期限に保存。
- ネットワーク漏洩:キーがTendermint上でブロードキャストされるペイロードに入っている → すべてのピアとバリデータが見る;エージェントUI/デバッグエンドポイントからのHTTPレスポンスに入っている → ネットワークアクセス権を持つ誰でも露出;RPC呼び出し者に返されるエラーメッセージに入っている。
- キー導出漏洩:ニーモニック/シード/エントロピーがログされたまたは返された。
漏洩したエージェントキーは通常以下を可能にします:
- そのエージェントとして有効なABCIペイロードを送信
- Safe トランザクションに共署(1-of-N またはクォーラム達成シナリオで)
- チェーン上でエージェントのガス予算を使い果たす
- ACN でエージェントになりすまし
ABCI 認証とリプレイモデル
ABCIペイロードは sender: str(エージェントアドレス)を含みます。フレームワークはTendermint署名を通じてペイロードがクレーム送信者によって署名されたことを検証します。その後ラウンドは以下を検証します:
senderがアクティブ参加者セットに入っている- ペイロードタイプがラウンドの
payload_classと一致 - しきい値ルール(例:
CollectSameUntilThresholdRoundは N 個のエージェントが同意する必要)
フレームワークが保証すること(標準ラウンドに対する調査結果として再報告しないでください):
- 標準ラウンド上のクロスピリオドリプレイ保護。
BaseTxPayload.round_countは単調で、ピリオド全体でリセットされません。標準収集ラウンド(CollectSameUntilThresholdRoundなど)はそれをprocess_payload()で検証します(packages/valory/skills/abstract_round_abci/base.py:1417):if payload.round_count != self.synchronized_data.round_count: raise ABCIAppInternalError(...)。閉じられたピリオドのペイロードは、ラウンドのprocess_payloadが親チェックを呼び出す限り、後のピリオドで再送信できません。
フレームワークが検証しないこと:
- ペイロードフィールドセマンティクス:「1 ETH を持っている」と報告するエージェントは実際のオンチェーン残高に照らし合わされません。フィールドレベルの検証はラウンド/動作作成者の責任です。
- 親チェックをバイパスするカスタムラウンド上のクロスピリオドリプレイ。 標準的な
round_count検証を呼び出さずにprocess_payload()をオーバーライドするラウンドはリプレイ表面を再開きます。これが H6 が監査する表面です。 - AEA アイデンティティ外の送信元認証:エージェントのキーが盗まれた場合、攻撃者は正当なエージェントと区別できません。ペイロードごとのTOFUまたは帯域外確認はありません。
- ペイロードクラス アイデンティティ安定性:
_MetaPayloadはペイロードを"{module}.{ClassName}"でキーします。ペイロードクラスの名前変更またはそのモジュール移動は永続Tendermint状態の逆シリアル化を破壊します — およびロールアウト中に2つの異なるペイロードタイプがレジストリキーを共有するウィンドウを作成します。交差参照:audit-fsmM1(ペイロードクラス不一致)および T6(_MetaPayload.registry が保存/復元されていない)。
IPFS ロード戦略モデル(customs/)
スコープ注意事項。 customs/ および FILE_HASH_TO_STRATEGIES は ダウンストリームサービスパターン(例:valory-xyz/trader、valory-xyz/optimus) — open-autonomy 自体には存在しません。フレームワークレポに範囲を限定した監査はこのセクションおよびC3に対して空の「調査結果なし」出力を生成します。このパターンを採用するダウンストリームサービスを監査する場合にのみこのサブセクションを適用してください。
customs/ 下の戦略(例:kelly_criterion、fixed_bet)はIPFSハッシュでランタイムにロードされます:
- ハッシュは
aea-config.yaml/service.yamlで設定されます — 通常FILE_HASH_TO_STRATEGIESのようなパラメータとしてIPFSハッシュを戦略モジュール名にマップします。 - コードはIPFSから取得され、コンテンツハッシュは設定されたハッシュに対して検証され、モジュールは エージェントプロセスで実行 されます。
信頼境界: 設定されたハッシュはエージェントと任意のコード実行の唯一のものです。戦略コードはフルエージェント権限で実行されます:
- エージェントの
Wallet/CryptoStore(aea.crypto.wallet)を通じたプライベートキーへのアクセス - 環境変数へのアクセス
- すべての設定エンドポイント(RPC、エクスチェンジAPI、IPFS)へのネットワークアクセス
synchronized_data(コンセンサス重要状態)を読み書きする能力
脅威表面:
- 間違ったハッシュ(タイプ、設定ミス、悪意のある設定注入) → エージェントは攻撃者選択コードを取得して実行します。
- 正当なコードを指すが第三者によってアップロードされたハッシュ → IPFSピンニングサービスまたは攻撃者がハッシュを制御する場合、エージェントはハッシュが解決するものを何でも実行します。
- ロードされたが型コントラクトに対して検証されていない戦略 → 戦略は予期しない方法でグローバル状態を変動させることができます(例:
Web3.eth.send_raw_transactionをモンキーパッチ)。
設定 / 環境変数解決
skill.yaml、aea-config.yaml、service.yaml は環境変数の補間をサポートします:
api_url: ${API_URL:str:https://default.example}
api_key: ${API_KEY:str:dummy}
解決はエージェント起動時に発生します。解決された値は Params / Model インスタンスにフローし、ランタイムに動作によって読み込まれます。
脅威表面:
- 本番環境での
dummy/ 空のデフォルト:環境変数が設定されていない場合、エージェントはプレースホルダで実行されます。認証されていないリクエストを認証されたエンドポイントに、間違ったアドレス、「テスト」キー。 docker-compose.yamlでgitに保存された環境変数:リポジトリへの読み取りアクセス権を持つ誰でも秘密を持っています。- コンテナイメージレイヤーに焼き付けられた環境変数値:
DockerfileのENV API_KEY=...はランタイムにオーバーライドされても イメージに永続化します。 - 環境変数値が
subprocess/ シェルコールにフローしている サニタイゼーションなし:コマンド注入。 - 環境変数値がPythonモジュールパスとして使用されている(
importlib.import_module(os.environ['MODULE'])):RCE。
Tendermint ネットワーク表面
各エージェントはTendermintサイドカーを搭載します:
- RPC ポート(デフォルト 26657) — ABCI クエリ、ブロック情報、ブロードキャストに使用
- P2P ポート(デフォルト 26656) — ピア間コンセンサス
- ABCI アプリソケット(デフォルト 26658) — エージェントの
abci接続がリッスンするポート(packages/valory/connections/abci/connection.py:110DEFAULT_ABCI_PORT);Tendermint はダイヤルしてCheckTx/DeliverTxなどを配信します。ここの 0.0.0.0 バインドはTendermint をバイパスして任意のピアがアプリケーションを直接ドライブできます - gRPC ポート(デフォルト 9090、オプション)
脅威表面:
- 0.0.0.0 で公開されたRPC (localhost / エージェントネットワークではなく) → すべてのコンセンサス状態の外部読み取り
- インターネット公開のP2P (永続ピアリストなし) → DOS 増幅、シビル耐性が損なわれました
- 誤置またはワールド読み取り可能なTendermint バリデータキー(
priv_validator_key.json) → コンセンサス署名偽造
コンテナ / デプロイメント脅威表面
autonomy deploy build は docker-compose / k8s マニフェストを生成します。一般的なデフォルト:
- Tendermintとエージェントプロセスはオーバーライドされていない限り root で コンテナで実行
- キーはホストからのボリュームマウント経由でマウント
- ログはマウントされたボリュームに書き込まれます
- ヘルス/デバッグエンドポイント可能性により公開される(例:ポート8080のFlask Tendermint モニタ)
脅威表面:
- ルートイン コンテナ = コンテナエスケープ → ホスト侵害はより広い影響半径を持っています
- ワールド読み取り可能なマウントされたキーファイル
- 認証なしで同期状態、バリデータ情報、またはエージェントアドレスを返すヘルスエンドポイント
- 本番ビルドで内部状態を公開するデバッグルート
依存関係サプライチェーン
Open-autonomy は poetry / pipenv および tomte をツーリングに使用します。ライセンスポリシー(CLAUDE.md 当たり):
- 許可:MIT、BSD、Apache 2.0
- 禁止:GPL、LGPL、MPL
サードパーティ取引ライブラリ(py_clob_client、web3、httpx、requests、エクスチェンジ固有クライアント)はフルキーチェーンアクセス権を持つフルトラストランタイム依存関係です。
脅威表面:
- 既知だがパッチされていないCVE で固定された依存関係
- タイポスクワット(例:
python-requestsvsrequests、crpytographyvscryptography) - ピン留めなしの推移的依存関係 → CI/開発/本番全体でのロックファイル漂流
- 開発のみの依存関係が本番に出血(
bandit、safetyがランタイムコンテナで) - アップストリームパッケージの侵害されたリリース(稀だが高影響)
- ホイールが利用できないの署名されていないソース配布
リポジトリの tox -e safety 許可リストはすでに推移的な依存関係で既知のパッチされていないCVEをピン留めしています。許可リスト自体を監査します。
監査チェックリスト
クリティカル(C)— 即座の侵害(RCE、キー露出、フルエージェント乗っ取り)
C1: 信頼できない入力への動的コード実行
何: eval、exec、compile、または入力が静的に既知ではない動的インポート。信頼できない入力には以下から取得されるものが含まれます:HTTPリクエスト、ABCIペイロード、環境変数、ファイルコンテンツ、IPFS、外部APIレスポンス。
検索パターン:
eval(、exec(、compile(—packages/、customs/、autonomy/内の任意の使用importlib.import_module(、__import__(非リテラル引数を持つ- 同じ信頼境界によって生成されないデータの
pickle.load、pickle.loads(ユーザによって書かれたファイル、ネットワークレスポンス、IPFSペイロード) marshal.loads、shelve.open信頼できないデータyaml.load(...)Loader=SafeLoaderなし — PyYAML < 5.4FullLoaderは CVE-2020-14343(任意オブジェクト構築)を持っていました;PyYAML ≥ 6.0 はLoaderがない場合TypeErrorを発生させます。PyYAML 6 でも明示的にLoader=SafeLoader(またはyaml.safe_load)を常に渡してください — 将来のローダーデフォルト変更に対するロバストネスのためsubprocess.*withshell=TrueAND 補間された引数(f"cmd {var}"、"cmd " + var、cmd % var)os.system(補間された引数を持つTemplate(...).substitute(...)ここで テンプレート自体が信頼できない入力から来ます
バグ例:
# バグ:ペイロードフィールドがシェルに補間される
def process_strategy(self, payload):
strategy = payload.strategy_name
subprocess.run(f"python -m {strategy}", shell=True) # RCE
修正: eval/exec を決してしない;yaml.safe_load を使用;subprocess.run([cmd, arg1, arg2], shell=False) を使用;pickle に対してはサインして検証するか JSON に置き換えます。
深刻度のエスカレーション: 入力源がABCIペイロードまたはIPFSコンテンツである場合、これは 無条件でクリティカル — 単一の悪意のある/侵害されたピアはすべてのエージェント上でRCEにピボットできます。
C2: プライベートキー露出
何: AEA暗号化/ウォレット境界(aea.crypto.wallet.Wallet、Crypto.sign_message、CryptoStore)外のプライベートキー、ニーモニック、シード、または署名材料を発行、永続化、または返すコードパス。
検索パターン:
logger.*、print(、return、レスポンスビルダー、ペイロードコンストラクター内の変数名正規表現:private_key、priv_key、pk、sk、secret、seed、mnemonic、entropy、signing_key、wallet.private_key
- エージェントの
Wallet/CryptoStoreから読み取り、値をレスポンスボディで返すHTTPハンドラー(特にデバッグエンドポイント) - 署名材料をTendermint経由でブロードキャストされる
payloadフィールドに補間する動作 - エージェントによって書き込まれたキー材料を含むファイル(
open(..., 'w')キー本体を持つ) - キーをエラーメッセージに含む例外ハンドラー(
raise ValueError(f"Bad key: {key}")) - キーを含むウォレット/署名者オブジェクトの
__repr__/__str__
バグ例:
# バグ:完全なHTTPレスポンスボディログはエージェントキーを含む Authorization ヘッダーを含みます
self.context.logger.info(f"Sent: {request}, Got: {response.json()}")
# リクエストはプライベートキーから導出された署名メッセージを含みます
交差参照: audit-fsm L4 はこれを操作レベルでカバーします。/security-review は影響が永続的露出であるため、クリティカルにエスカレートします。
修正: キー材料を決してログしない;__repr__ で削除;キーアクセスを sign(...) ではなく get_key() を公開しない単一モジュールに制限;すべてのデバッグエンドポイントをレビュー。
C3: IPFS 戦略ハッシュ信頼バイパス
何: ハッシュ検証なしでIPFSからPythonモジュールをロードするコードパス、OR設定されたハッシュが信頼できない入力からランタイムで導出されることを可能にする。
検索パターン:
- IPFS フェッチ + 取得バイトの
importlib/exec/compile FILE_HASH_TO_STRATEGIES(または同様のパラム)が静的設定ではなく外部ソースから入力される- ハッシュチェックなしでロードして評価するカスタムズ/ローダーコード
- プレースホルダにデフォルトするハッシュが環境変数で設定される(
dummy、空)— 本番エージェントは検証されていない戦略で実行される可能性があります
脅威: IPFSハッシュは信頼境界です。それをバイパスすることは = フルエージェント権限を持つ任意のコード実行(キー、ネットワーク、オンチェーン権限)。
修正: ハッシュを静的に設定;実行前にコンテンツハッシュが設定されたハッシュと一致することを検証;本番ビルドでプレースホルダのデフォルトを拒否。
C4: ABCI / ネットワーク境界での安全でない逆シリアル化
何: コード実行を可能にするフォーマット(pickle、yaml.load、marshal)を使用してインバウンドペイロードを逆シリアル化する接続/ハンドラーコード。
検索パターン: connections/*/connection.py で、handlers.py、ABCIメッセージハンドラー:
pickle.loads(message.body)、pickle.loads(srr_message.payload)yaml.load(...)Loader=SafeLoaderなしmarshal.loads(...)- フィールド値を
evalするカスタムデシリアライザー
audit-resilience BP14 とは別です。 BP14 は json.loads(message.payload) から接続の on_send / _route_request がキャッチするかどうかを監査します — すなわち形式が正しくない入力堅牢性懸念。C4 は逆シリアライザー自体がコード実行しているかどうかを監査します — すなわち RCE 懸念。接続は同時にBP14調査結果(例外処理がない)とクリーンC4(json.loads を使用)を持つことができます、またはその逆(pickle.loads を太い try-except 内 → C4 調査結果なしBP14)。異なる脅威クラス;独立して報告。
修正: JSON を使用;バイナリフォーマットが必要な場合は厳格なスキーマを持つprotobuf/msgpackを使用。
C5: ソースツリーのハードコード秘密
何: APIキー、JWT、ニーモニック、プライベートキー、OAuth トークン、AWS認証情報、または埋め込みトークンを持つウェブフック URL、ソース内にコミット。
ツーリング: tox -e gitleaks はCI で実行されます。/security-review は再実行してレビュー:
- 現在の
gitleaks.toml許可リストが過度に広いパターンのため - 監査スコープに追加された新しいファイル
- テストフィクスチャは実行時コードパスに誤ってプロモートされた可能性があります
検索パターン gitleaks のデフォルトを超えて。Gitleaks のビルトインルールはすでに一般的なSaaS/クラウドトークン形状(Slack、GitHub、GitLab、AWS、Stripe、JWT、OpenAI など)をカバーします — これらのリテラルをここにリストしないでください、それらをリストするとこのファイル上でgitleaksを再トリガーします。監査固有の追加:
0x[a-fA-F0-9]{64}— 32バイト16進数 形状 非テストファイルで。高い偽陽性率:同じフォームはEthereumトランザクションハッシュ、ブロックハッシュ、Keccak-256出力、ストレージスロットキー、IPFS CID v1バイナリフィールド、およびあらゆるbytes32リテラルと一致します。フラグする前にトリアージ:{key, secret, mnemonic, pk, sk, private}の変数名の近さを要求、OR{tx_hash, block_hash, ipfs_hash, topic, slot}に隣接する一致を除外します。このトリアージなしで、ルールはテストとツーリングのすべてのブロックハッシュリテラルで発火し、**レビュアーは実際のキーを「単なるハッシュ」として却下できますmnemonic = "..."、ニーモニック形 12/15/18/21/24 単語の文字列がソース内
深刻度: 意図に関わらずクリティカル — コミットされると、削除後も(git履歴保持)侵害されると想定する必要があります。
修正: 露出された認証情報を回転;履歴から削除(git filter-repo);環境変数またはシークレットマネージャー参照に置き換え;テストされた負として gitleaks.toml に追加。
C6: シェルサブプロセス補間経由のコマンド注入
何: subprocess.*(..., shell=True) または os.system(...) ここで任意の引数は外部入力(環境変数、ペイロードフィールド、HTTPクエリパラメータ、ファイルコンテンツ)から構成されます。
検索パターン:
subprocess.run(、subprocess.call(、subprocess.Popen(withshell=Trueos.system(、os.popen(commands.getoutput((Python 2 レガシーの場合)、pty.spawn(
各について、引数が静的リテラルか補間かを確認。
バグ例:
# バグ:HTTPリクエストからの agent_id がシェルにフロー
@app.post("/restart")
def restart(agent_id: str):
subprocess.run(f"systemctl restart agent-{agent_id}", shell=True)
修正: shell=False を使用して argv をリストとして渡す;回避不可能なシェルパスに shlex.quote を使用;補間の前に許可リストで検証。
高い(H)— 即座のRCEに満たない高影響問題
H1: 安全でないデフォルトを持つ環境変数駆動型認証
何: service.yaml / aea-config.yaml / skill.yaml と環境変数補間された認証認証情報である dummy、空の文字列、またはプレースホルダがデフォルト。本番デプロイメントは環境変数が設定されることに依存;そうでなければエージェントは認証されていない、または共有される既知の悪い認証情報で実行されます。
YAML設定の検索パターン:
${[A-Z_]+:str:dummy}、${[A-Z_]+:str:}、${[A-Z_]+:str:test}、${[A-Z_]+:str:placeholder}*_api_key、*_token、*_secret、*_password、*_credentialに一致するパラム名*_url、*_endpointに一致するパラム名 ここでプレースホルダが疑わしい(localhost、example.com)
修正: 環境変数を要求(デフォルトなし)、または 失敗する閉じた 値にデフォルト(例:読み取り専用操作のみを許可する認証されていないクライアント);スタートアップチェックを追加して本番モードでプレースホルダ値での実行を拒否。
H2: デプロイメント成果物のハードコード秘密
何: docker-compose.yaml、Dockerfile*、kubernetes.yaml、helm/ チャート、GitHub Actionsワークフロー、または .env* ファイルでリポジトリにコミットされたファイル内の秘密。
検索パターン:
Dockerfile*:ENV API_KEY=、ARG SECRET=、RUN echo "..." > /keydocker-compose.yaml:environment:ブロック内のリテラル値(${VAR}参照対).github/workflows/*.yml:リテラルトークン(${{ secrets.X }}対).env、.env.local、.env.productiongitにコミット(これらは.gitignore内である必要があります)kubernetes/*.yaml:base64エンコードされたプレーンテキスト(Secretマニフェスト)を持つdata:ブロック
修正: Docker秘密 / Kubernetes Secret リソースを使用してマウントされたファイル;GitHub Actions 暗号化秘密を使用;.env* が gitignored であることを確認;見つかった値を回転。
H3: ルートで実行されているコンテナ
何: USER ディレクティブなし、または USER root で Dockerfile がコンテナ内でルートとして実行されるままエージェントプロセスを残します。
検索パターン: Dockerfile*、特に deployments/Dockerfiles/*/Dockerfile:
USERディレクティブの不在(Docker デフォルト = root)USER root明示的に設定RUN chown -R root:root /appパターン
なぜクリティカルではなく高いか: コンテナ内のルートは即座のホストでのRCEではありませんが、任意のコンテナエスケープCVE(例:cgroup脆弱性、カーネルバグ)と結合すると、影響半径は非ルートよりもはるかに大きいです。
修正: 非ルートユーザーを作成(adduser --system --no-create-home agent)、USER agent、マウントされたキーファイルがそのuid のみで読み取り可能であることを確認。
H4: ローカルネットワーク外に公開される Tendermint RPC
何: Tendermint RPC ポート(デフォルト 26657)を 0.0.0.0 にバインドされた、またはauth なしで docker-compose.yaml ports: セクションで公開。
検索パターン:
docker-compose*.yaml:26657 / 26656 をホストに公開するports:エントリ- Tendermint 設定(
config.toml):tcp://127.0.0.1:26657ではなくladdr = "tcp://0.0.0.0:26657" - Tendermint の Kubernetes Service マニフェスト
type: LoadBalancerを持つ
脅威: Tendermint RPC はブロックデータ、バリデータ情報、メモリプールの状態を公開し、(一部の構成では)broadcast_tx_* エンドポイントはトランザクションを送信することを誰でも可能にします。
修正: localhost または エージェント内部ネットワークにバインド;外部RPC アクセスに対して auth プロキシを使用するネットワークポリシー/ファイアウォールを使用して入力制限。
H5: ABCI ペイロードフィールド検証ギャップ
何: end_block() または process_payload() で読み取られるペイロードフィールドが明示的な検証なしでセキュリティ重要なコンテキスト(署名材料、アドレス、量、コントラクトアドレス、URL)で使用されます。
検索パターン:
payload.<field>を読み取り、以下に使用するラウンド/動作コード:Web3.toChecksumAddress(...)、Account.sign_message(...)、コントラクト書き込み呼び出し、ユーザ制御URL へのHTTPリクエストstrまたはAnyとして入力されるペイロードクラス(Pydantic /データクラス検証フックなし)
脅威シナリオ: 侵害されたエージェントは悪意のあるURL、アドレス、または量を持つペイロードを送信します。ラウンドが境界チェックなしでペイロードを受け入れると、コンセンサス値はすべてのエージェント全体の下流操作を駆動します。
修正: check_payload() で検証(ラウンド側)およびペイロード構築(動作側);厳密な型ヒント(Address、URL、PositiveInt)を使用;範囲外の値を拒否。
H6: カスタムラウンドのリプレイ保護ギャップ
何: 標準収集ラウンドはフレームワークから process_payload() を継承し、payload.round_count == self.synchronized_data.round_count を検証します(packages/valory/skills/abstract_round_abci/base.py:1417)。H6 監査はより狭い残余表面:親チェックを呼び出さずに process_payload() をオーバーライドするカスタムラウンド(例:super().process_payload(payload) または同等の round_count アサーション経由)。
確認方法:
process_payloadを定義するラウンドサブクラスについて Grep(def process_payload(self, payload)。- 各について、オーバーライドが以下のいずれかを行うことを検証:
super().process_payload(payload)を呼び出す、OR- 同等の
if payload.round_count != self.synchronized_data.round_count: raise ...チェックを実行。
- どちらでもない場合、このラウンドのペイロードはピリオド N から任意の後のピリオド M で再生できます — フラグ。
- オンチェーントランザクションを駆動するペイロードについて、結果のtxが chain-id、コントラクトnonce、Safe nonceを含むことを確認(これらはABCIレベルチェックから独立)。
脅威: 攻撃者はピリオド N の参加者によって署名されたペイロードをキャプチャし、ピリオド M で再送信して状態変更アクションを再トリガーします。標準ラウンド process_payload でこれを拒否;カスタムラウンドはしないかもしれません。
audit-resilience BP15 とは別です。 BP15 は同じ論理アクション が FSM リトライ/接続層リトライ(偶然、内部トリガー)経由で再送信されることに対して保護します。H6 は閉じられたピリオドからの古いペイロードがコンセンサスレイヤー上(敵対的、外部トリガー)で再生されることに対して保護します。異なる攻撃者モデル、異なる軽減表面 — 軽減は部分的に重複(アクション上のべき等対ペイロード上の nonce/round_count)ですが独立した評価が必要です。
修正: すべてのカスタム process_payload オーバーライドで、最初に super().process_payload(payload) を呼び出すか、または round_count チェックを明示的に複製。
H7: 依存関係CVE
何: tox -e safety を実行(tomte の許可リストを使用)解決された環境に対して。ランタイム依存関係のアドレスされていない各CVEは調査結果です。pip-audit はオプション二次ソースカバレッジですが、このリポジトリ内で事前設定されていません — tox.ini に [testenv:pip-audit] スタンザはなく、make security は safety、bandit、gitleaks のみを実行します。pip-audit クロスチェックが必要な場合は、手動でインストール(pip install pip-audit)して個別に実行;レポートで注記します。
プロセス:
tox -e safetyを実行。オプションpip install pip-audit && pip-audit -r <lockfile>を二次ソースカバレッジのため。- 許可リスト内にない各CVEについて、ドキュメント:パッケージ、バージョン、CVE ID、アップストリームあたりの深刻度、このコードベース内の悪用可能性(エージェント は脆弱なコードパスに到達しますか?)。
- 既存のtomteリスト(
tox.iniの-i 37524 -i 38038 ...)を監査 — ピン留めされた各CVEについて、アップストリームがピンを削除することを可能にする修正を出荷したかどうかを確認。
修正: 依存関係をアップグレード;アップグレードが不可能な場合、許可リストに日付付き軽減を文書化して四半期ごとに再確認;到達不可能なCVEについて、なぜそれらが適用されないかを文書化。
中程度(M)— 強化ギャップと弱い検証
M1: コンテナ内のワールド読み取り可能なキーファイル
何: マウントされたプライベートキーファイル(許可モード 0644、0755 を持つ)、またはchmod なしで作成されたコンテナ内部コピー。
検索パターン:
Dockerfile*:その後のRUN chmod 600なしでCOPY ethereum_private_key.txtdocker-compose*.yaml:明示的なread_only: trueなしのキーファイルのボリュームマウント- chmod 600 なしでキーをコピーするセットアップスクリプト
defaultMode: 0644を持つ Kubernetes Secret マウント
修正: コピー/マウント後 chmod 600 *_private_key.txt;read_only を使用してマウント;Kubernetes Secret defaultMode: 0400 を使用;その uid のみで読み取り可能をマウント。
M2: 内部状態を公開するデバッグ/ヘルスエンドポイント
何: Flask Tendermint モニタ(ポート8080)、エージェント デバッグルート、または {"status": "ok"} 以上を返すヘルスエンドポイント — 例:エージェントアドレス、バリデータ情報、署名ペイロード数、設定パラム、最後のブロック。
検索パターン:
packages/、autonomy/、deployments/のflask.*route(、@app.route(、@app.get(、@app.post(make_response(、jsonify(豊かな構造を返すsynchronized_data、params、address、validatorを含むレスポンスボディ
脅威: ターゲット攻撃のための偵察。バリデータアドレス + チェーン → 資金トレース;設定されたRPC → MITM ターゲットリスト;エージェントアドレス → オンチェーンアイデンティティ露出。
修正: ヘルスレスポンスから不要な フィールドを削除;DEBUG=true 環境変数の背後にある ゲートデバッグ ルート;任意の内部状態エンドポイントに対してauth を要求。
M3: HTTP ハンドラー信頼境界での弱い検証
何: handlers.py のHTTPハンドラーがスキーマ検証なしでリクエストボディを受け入れます。Audit-resilience はクラッシュパターンをカバー;/security-review M3 は悪用可能性をカバー:
- SQLインジェクション(エージェントでは稀ですがチェック)
- リクエスト入力に基づいてファイルを読み書きするハンドラーでのパストラバーサル(
open(f"data/{request.name}.json")) - ハンドラーがリクエストから URL へのアウトバウンドリクエストを行う際のSSRF(
requests.get(request.url)) defusedxmlなしでXML パースが使用される場合のXXE
検索パターン:
open(補間されたパスコンポーネントrequests.get(...)リクエストから URLxml.etree.ElementTree.parse(、lxml.etree.parse(defusedxmlなし- SQLクエリを構築する f-文字列または
.format()
修正: ホワイトリストに対する入力の検証;ファイルシステムパスを解決してチェック(Path(...).resolve().is_relative_to(allowed_root));ユーザ制御アウトバウンドURLを許可しないか、許可リストホストに制限;defusedxml.ElementTree を使用。
M4: 暗号化の弱点
何:
- セキュリティ目的で使用されるMD5/SHA1(署名、MAC、パスワード ハッシュ)
- 暗号化でハードコードされたIV/nonce
- ECBモード ブロック暗号
- セキュリティクリティカルなランダム性に対して
random.*(secretsを使用) - カスタムHMAC実装(
hmac.compare_digestを比較のために使用)
検索パターン:
hashlib.md5(、hashlib.sha1(—verify、auth、sign、macコンテキストで使用される場合はフラグCrypto.Cipher.AES.MODE_ECB、AES.new(..., AES.MODE_ECB, ...)random.randint(、random.choice(、os.urandom((後者はOK ですが使用法をチェック)ここで値はキー、IV、nonce、またはトークンとして使用- HMACまたは署名の
==比較(タイミング攻撃)
修正: ハッシュ用にSHA-256+;暗号化用にAES-GCM/ChaCha20-Poly1305;トークン用に secrets.token_bytes(32);比較用に hmac.compare_digest。
M5: CORS のルース / セキュリティヘッダーの欠落
何: HTTPサービス(Flask Tendermint モニタ、エージェント UI)with Access-Control-Allow-Origin: * または セキュリティヘッダー(X-Content-Type-Options、X-Frame-Options、Strict-Transport-Security、Content-Security-Policy)の欠落。
検索パターン:
Access-Control-Allow-Originwith*flask_cors.CORS(app)デフォルト設定を持つ(= 許容的)- ヘッダー設定ミドルウェアの欠落
修正: CORSを既知のオリジンに制限;ミドルウェアを通じてセキュリティヘッダーを設定;読み取り専用エンドポイントについて、脅威モデルを明示的に文書化。
M6: ライセンス コンプライアンス漂流
何: CLAUDE.md に従い、MIT/BSD/Apache 2.0 のみが許可されます;GPL/LGPL/MPL は禁止。依存関係ツリーは推移的に禁止されたライセンスを含む可能性があります。
プロセス:
pip-licenses --format=markdownを実行(またはtomteのライセンスツーリングが利用可能な場合)解決された環境に対して。- GPL/LGPL/MPL/AGPL/SSPL/所有権のあるライセンスを持つ依存関係をフラグします。
- 推移的依存関係でのコピーレフトクリープを監査。
修正: 依存関係を置き換え;法的レビューで明示的な例外を追加;NOTICE/SBOM で文書化。
低い(L)— 深さで防ぐ観測可能性
L1: ログの秘密レダクション ポリシーの欠落
C2 は個別呼び出しサイト開示をカバー。L1 はシステムの質問を聞く:秘密形の値をマスクするログパイプライン(フォーマッター/structlog プロセッサー/logging.config.dictConfig フィルター)のレダクションレイヤーはありますか、または著者が個別に負担しますか?後者の場合、L1 としてファイル — 深さで防ぐギャップ。
L2: スタートアップ時間秘密検証チェックなし
何: H1 が修正されても(安全でないデフォルトなし)、必須秘密環境変数が設定され期待される形状(例:API_KEY は32+ 文字である必要があります、PRIVATE_KEY は64 16進数文字である必要があります)と一致することをアサートするスタートアップチェックに値があります。
修正: エージェント起動時に validate_secrets() 呼び出しを追加;必須秘密が不足またはマルフォームされていた場合は失敗させる明確なエラーで。
L3: Tendermint 永続ピアリスト ハードコード
何: サービスディスカバリーではなく静的に設定された persistent_peers。脆弱性ではありませんが、ピアチャーンに対するネットワークの弾力性を制限します。
修正: 情報として文書化;本番環境ではDNSベースまたはレジストリベースのピアディスカバリーを検討。
L4: SBOM / ビルド来歴
何: コンテナイメージは再現性/SBOM 証明で構築されますか?ホイールは検証済みPyPI ミラーからインストールされますか?ビルドパイプラインは署名されていますか?
修正: cyclonedx-py または syft 経由でSBOM を生成;cosign でイメージに署名;可能な場合は内部インデックスにピン。
L5: セキュリティ敏感イベントの監査ログカバレッジ
何: キー操作(キーファイル読み込み、オンチェーントx送信、ABCIペイロード署名、戦略ロード、設定リロード)は操作ログと異なる専用監査ログに記録されますか?これがなければ、事後インシデント フォレンジックは難しいです。
修正: セキュリティイベントを専用ロガー/外部監査シンクにルート;タイムスタンプ、エージェントid、操作、結果を含みます。
偽陽性ガイダンス
これらのパターンは疑わしく見えますが、設計によって正しいです。それらを報告しないでください:
テストフィクスチャプライベートキー
テストフィクスチャ(tests/、plugins/aea-test-autonomy/、conftest.py)は通常、決定的なテスト設定のためのハードコードテストプライベートキーを含みます。これらはHardhat/Ganache/test Tendermint で使用される周知の使い捨てキーです。これらをC5 としてフラグしないでください。C5 をテスト以外のコードパスに制限します。
テスト設定ファイルのダミー/プレースホルダ値
テストYAML設定(tests/test_data/、aea-test-autonomy フィクスチャ)はエルメティックテストのためプレースホルダURL/キー/アドレスを使用。H1 としてこれらをフラグしないでください — それらはデプロイされていません。
内部に生成されたデータの pickle.loads
pickle.loads が同じプロセスまたはコンテナ内でエージェント自体が書き込んだファイルまたはバッファを読み込む場合(例:ローカル キャッシュ復元)、ネットワーク入力のようにRCE公開されていません。深刻度を高いに低減し、信頼仮定に注記します。
subprocess.run(..., shell=False) 補間された引数を持つ
引数補間は shell=False の場合安全です。シェルは関与しないため — argv は execve に直接渡されます。これらをC6 としてフラグしないでください。C6 は shell=True を要求します。
非セキュリティ用途の random.*
ジッター、ログサンプリング、A/Bテスト バケッティングなどのための random.choice は問題ありません。M4 を出力がキー、IV、nonce、トークン、パスワード、または秘密を保護するものである使用に制限します。
認証なしの内部RPCポート
127.0.0.1 またはDocker 内部ネットワークにバインドされ、外部公開なしのTendermint RPC はフレームワークのデフォルトであり、OK です。H4 はポートがホスト インターフェースまたはルーティング可能なネットワークに公開される場合にのみ適用されます。
フレームワークメタプログラミング内の eval(
一部のフレームワーク内部コードは限定的な目的で eval を使用します(例:メタクラス init での enum.Enum 値強制)。入力が同じモジュール内で静的に構築され、ユーザ制御されない場合、C1 としてフラグしないでください。フラグする前に入力ソースを検証。
customs/ / package_overrides のハードコード コントラクトアドレス
コントラクトアドレスはオンチェーン公開です。それらは秘密ではありません。APIキーと混同しないでください。
方法論ガードレール
2 セットのガードレールが適用されます:/audit-fsm および /audit-resilience で既に文書化されている クロススキル、およびセキュリティ固有のもの下記。
兄弟の方法論ガードレール セクションからクロススキル ガードレールを適用してください、ここで再記載なし:
- すべてのサブエージェント調査結果を受け入れる前に検証 — ソースを読む、深刻度を確認、分割を統合、大幅に低減。
- フラグする前にデータ型トレースを強制 — ランタイムタイプ ≠ 静的注釈 JSON が境界を交差するとき。
- バグあたり単一調査結果 — ルート原因 = すべての関連IDを引用する1つのレポートエントリ。
これらは複製を削減し、兄弟スキルが進化するときの漂流を防ぎます。以下はセキュリティレビューに本当に特定のガードレールです。
露出から露出を区別
- 露出 = 秘密は信頼境界を離れました(ログ、レスポンス、ペイロード、エージェント
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- valory-xyz
- ライセンス
- Apache-2.0
- 最終更新
- 2026/5/12
Source: https://github.com/valory-xyz/open-autonomy / ライセンス: Apache-2.0
関連スキル
secure-code-guardian
認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。
claude-authenticity
APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。
anth-security-basics
Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。
x-ray
x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。
semgrep
Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。
ghost-bits-cast-attack
Java「ゴーストビッツ」/キャストアタック プレイブック(Black Hat Asia 2026)。16ビット文字が8ビットバイトに暗黙的に縮小されるJavaサービスへの攻撃時に使用します。WAF/IDSを回避して、SQLインジェクション、デシリアライゼーション型RCE、ファイルアップロード(Webシェル)、パストトラバーサル、CRLF インジェクション、リクエストスマグリング、SMTPインジェクションを実行できます。Tomcat、Spring、Jetty、Undertow、Vert.x、Jackson、Fastjson、Apache Commons BCEL、Apache HttpClient、Angus Mail、JDK HttpServer、Lettuce、Jodd、XMLWriterに影響し、WAFバイパスにより多くの「パッチ済み」CVEを再度有効化します。