PraisonAI: AgentOSは、デフォルトでネットワークに公開され、認証なしで動作するため、未認証のAgentの呼び出しや指示の開示が可能

## 概要

`praisonai`というTypeScript/npmパッケージに含まれるAgentOSサーバーには、セキュリティ上の問題があるデフォルト設定が含まれています。具体的には、`0.0.0.0`にバインドされ、APIキーが設定されておらず、CORSの設定が`*`で、認証情報も使用されています。APIキーのミドルウェアは、APIキーが設定された場合にのみ登録されるため、ドキュメントに記載されている簡単なセットアップ方法(`new AgentOS({agents:[...]}).serve({port})`)では、**認証なしで**、`GET /api/agents`(これにより、Agentの名前、役割、指示(システムプロンプト)が漏洩する)と`POST /api/chat`(これにより、Agentが呼び出される)が公開されます。ネットワーク上のどのデバイスからも、Agentのシステムプロンプトを読み取ることができ、Agentを操作することができます。実行時に確認済み。深刻度:高。

## 詳細

### 影響を受けるコンポーネント
- パッケージ: `praisonai` (npm / TypeScript)。ファイル: `src/praisonai-ts/src/os/config.ts` および `src/praisonai-ts/src/os/agentos.ts` (`AgentOS`)。

### 脆弱なコード / 根本原因

パス:
`src/praisonai-ts/src/os/config.ts`

クラス/定数:
`DEFAULT_AGENTOS_CONFIG` / `mergeConfig`

コードスニペット:
```ts
export const DEFAULT_AGENTOS_CONFIG = {
host: '0.0.0.0',
corsOrigins: ['*'],
apiKey: '',
// ...
};
// mergeConfig: apiKey = userConfig?.apiKey ?? process.env.PRAISONAI_AGENTOS_API_KEY ?? '';
```
問題点: デフォルト設定では、すべてのインターフェースにバインドされ、APIキーは空であり、CORSはワイルドカード設定になっています。`apiKey`は、開発者が明示的に設定しない限り、空のままです。

パス:
`src/praisonai-ts/src/os/agentos.ts`

関数:
`serve` / `_registerRoutes` (Expressアプリケーション)

スニペット:
```ts
if (this.config.apiKey) { // auth middlewareは、apiKeyが設定されている場合のみ追加されます
app.use((req,res,next) => { /* Bearer/x-auth-tokenが一致しない場合は401エラー */ });
}
// ルート:
app.get(`${apiPrefix}/agents`, ...) // エージェントの名前、役割、指示を返します
app.post(`${apiPrefix}/chat`, ...) // agent.chat(message)を呼び出します
```
問題点:認証の仕組みは、`apiKey`が空でない場合にのみ有効になります。デフォルトでは`apiKey`が空であるため、認証ミドルウェアは登録されず、`GET /api/agents`(システムプロンプトの開示)および`POST /api/chat`(エージェントの呼び出し)が、ネットワーク上のどのクライアントにも提供されます。CORSの設定では、`Access-Control-Allow-Credentials: true`がワイルドカードのオリジンに対して設定されています。

### 攻撃の流れ
1. 開発者が、`apiKey`/`PRAISONAI_AGENTOS_API_KEY`を設定せずに、クイックスタートでAgentOSをデプロイします。
2. ネットワーク上のどのクライアントからも、`GET /api/agents`が呼び出され、エージェントの指示/システムプロンプトが受信されます。
3. ネットワーク上のどのクライアントからも、`POST /api/chat`が呼び出され、エージェントが呼び出されます。

### 既存の保護が回避される理由
デフォルトの設定では、保護は存在しません。`apiKey`が空(デフォルト)の場合、認証の仕組みがスキップされ、サーバーはすべてのインターフェースにバインドされます。

### セキュリティ境界
認証されていないネットワークからの、エージェントのメタデータへのアクセスと、エージェントの呼び出し。これは、TSパッケージで再発するCVE-2026-44338の典型的な脆弱性であり、さらに悪質なケース(デフォルトでは0.0.0.0にバインドされます)。

## 概念実証

### 環境
`src/praisonai-ts`から取得した実際のAgentOSを、デフォルト設定(スタブエージェント、LLMは不要)でts-nodeを使用してNodeコンテナ内で実行します。`127.0.0.1:18000`。実行可能なアセット:`PraisonAI-Runtime-Repro\runtime-files\` (`docker-compose.agentos.yml`)。

### 再現手順
1. `PRAI-01-01-AgentOS-Agents-NoAuth`: `GET /api/agents`(認証なし)→ `127.0.0.1:18000`。
2. `PRAI-01-02-AgentOS-Chat-NoAuth`: `POST /api/chat {"message":"hello from attacker"}`(認証なし)。

### 期待される結果
ローカルネットワーク以外のアクセスには認証が必要であり、エージェントの指示は認証なしで開示されるべきではありません。

### 実際の結果
- `GET /api/agents` → `200`、 `"instructions":"SYSTEM PROMPT SECRET ... PRAISONAI_INTERNAL_SECRET_CANARY_7f3a91"` が漏洩; レスポンスヘッダー `Access-Control-Allow-Credentials: true`。
- `POST /api/chat` → `200`、エージェントが呼び出された (`"response":"...PRAISONAI_AGENTOS_CANARY_7f3a91..."`)。

### スクリーンショット

**認証なしの `/api/agents` からエージェントの指示が漏洩**

`Authorization` ヘッダーなしで `/api/agents` への GET リクエストが成功します。レスポンスには、エージェントのメタデータと指示が含まれており、その中にカナリアシステムのプロンプトの値が含まれています。

<img width="1535" height="829" alt="01-AgentOS-Agents-NoAuth" src="https://github.com/user-attachments/assets/705087e1-8017-46f6-9a91-edb8312e2f26" />

**認証なしの `/api/chat` でエージェントが呼び出される**

`Authorization` ヘッダーなしで `/api/chat` への POST リクエストが成功します。レスポンスは、攻撃者が制御するメッセージが、設定されたエージェントによって処理されたことを確認しています。

<img width="1537" height="833" alt="02-AgentOS-Chat-NoAuth" src="https://github.com/user-attachments/assets/5cdf8f56-b8d8-498b-87bd-44834f39998c" />

### 再現に必要なファイル
添付されたアーカイブには、この問題を再現するために使用されたローカルの Docker ランタイムが含まれています。このアーカイブには、実際のシークレット、サードパーティの API キー、または本番環境の認証情報は含まれていません。

[PraisonAI-Runtime-Repro.zip](https://github.com/user-attachments/files/29143421/PraisonAI-Runtime-Repro.zip)

## 影響
認証なしでのエージェントの設定/システムプロンプトの開示; 認証なしでのエージェントの呼び出し; LLM のコストの不正利用; 設定されたエージェントのツールによっては、ツールの不正利用の可能性; 許可的な CORS-with-credentials。

## 推奨される対策
- デフォルトの `host` を `127.0.0.1` に設定; ループバック以外の接続には `apiKey` を必須とする (fail closed)。
- `corsOrigins` をデフォルトで `['*']` に設定しない。特に `Access-Control-Allow-Credentials: true` の場合。
- 認証されていないエンドポイントで、完全な `instructions` を返さない。

影響を受けるパッケージ:
- npm (JavaScript) praisonai: 影響あり < 1.7.3、1.7.3 で修正済み。