mcpField
S
security

security

github.com/cognitedataセキュリティ338 回インストール
リポジトリ

security について

Dune アプリ向けのセキュリティ監査スキルです。一般的なリスクの確認と修正を順に進め、未解決の問題を報告します。

主な機能

  1. 01ルートとデータフローの把握
  2. 02CDF 呼び出しを Cognite SDK へ移行
  3. 03秘密情報と DOM 注入の確認
  4. 04認証と入力検証の監査
  5. 05Vite 設定と依存関係の確認
  6. 06未解決項目の報告

活用シーン

  1. 01デプロイ前の Dune アプリ監査
  2. 02生の CDF リクエストを SDK 呼び出しに変更
  3. 03認証情報漏えいと危険な DOM 操作の検出

インストール

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

$npx skills add https://github.com/cognitedata/dune-skills --skill security

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

詳細

セキュリティ修正

$ARGUMENTS(引数が指定されていない場合はアプリ全体)のセキュリティ問題を見つけて修正します。以下の各手順を順番に実施してください。問題が見つかった手順では、必ず修正も行ってください。


Step 1 — 攻撃対象領域を把握する

確認を始める前に、以下のファイルを読んでください。

  • src/main.tsx / src/App.tsx — エントリーポイント、ルーティング、認証ガード
  • vite.config.ts — 開発サーバーのプロキシ、CORS、ヘッダー
  • package.json — サードパーティ依存関係の一覧
  • **/auth*、**/login*、**/token*、**/credential* に一致するすべてのファイル

以下を特定してください。

  • すべてのページ/ルートと、それぞれに認証ガードが適用されているかどうか
  • 外部データがアプリに入るすべての箇所(CDF SDK 呼び出し、fetch、ユーザーのフォーム入力)
  • データが書き戻されるすべての箇所(CDF の upsert、fetch の POST/PUT/DELETE)

Step 2 — CDF へのアクセスをすべて Cognite SDK に移行する

**Cognite Data Fusion(CDF)**へのすべての通信は、公式 Cognite SDKを経由する必要があります。SDK を迂回する、CDF に類するホストや API への HTTP、WebSocket、その他のネットワーク呼び出しをすべて見つけ、SDK を使用するよう書き換えてください。

生の HTTP 呼び出しを検索する
# Find fetch, axios, XMLHttpRequest, and other HTTP client usage
grep -rn --include="*.ts" --include="*.tsx" --include="*.js" \
  -E "(fetch\(|axios\.|axios\(|XMLHttpRequest|\.ajax\(|http\.get\(|http\.post\(|request\()" src/

# Find raw URL construction that looks like CDF endpoints
grep -rn --include="*.ts" --include="*.tsx" \
  -E "(cognitedata\.com|cognite\.ai|/api/v1/projects|cdf\.|\.cognite\.)" src/

# Find custom Authorization or api-key headers
grep -rn --include="*.ts" --include="*.tsx" \
  -E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
修正方法

見つかった生の CDF 呼び出しごとに、周辺のコードを読み、対象となる CDF リソースと操作を確認してから、適切な SDK メソッドを使うよう書き換えてください。不要になった生の HTTP クライアントのインポートは削除してください。

パターン対応
CDF URL(*.cognitedata.com、/api/v1/projects/*)への fetch() または axios 呼び出しCognite SDK(cognite.files.getDownloadUrls(...)、cognite.timeseries.retrieve(...)、client.instances.search(...) など)を使うよう書き換えます
CDF トークンを含む独自の Authorization ヘッダー削除します — 認証は SDK が自動的に処理します
CDF エンドポイントへの WebSocket 接続SDK のストリーミングメソッドを使うよう書き換えます
内部で CDF に転送するプロキシエンドポイント内部で SDK を使うようプロキシを書き換えます
CDF 以外の URL への fetch()(静的アセット、文書化されたサードパーティ API)そのまま残します — 必要な理由を説明するコメントを追加してください

すべての CDF 呼び出しを書き換えたら、不要になった axios または fetch 関連のインポートを削除してください。

許容されるもの
  • sdk.files.*、sdk.timeseries.*、client.instances.* などを通じた、すべての CDF の読み取り/書き込み
  • 以下に該当する、CDF 以外のネットワーク呼び出し:
    • 既知の静的アセットホスト(CDN、画像サービス)への呼び出し
    • 製品に必要な、文書化されたサードパーティ API への呼び出し
    • アプリの README またはアーキテクチャドキュメントに明記された呼び出し

Step 3 — 認証情報とシークレットの管理を確認し、修正する

ハードコードされた認証情報や機密値を検索してください。

# Look for anything that smells like a secret in source files
grep -rn --include="*.ts" --include="*.tsx" --include="*.js" \
  -E "(password|secret|apikey|api_key|token|bearer|private_key)\s*=\s*['\"]" src/

ハードコードされたシークレットは、環境変数に置き換えてください。.env.example を作成または更新し、プレースホルダーを設定してください。.gitignore に .env がない場合は追加してください。

修正方法
  1. ハードコードされたシークレットをそれぞれ置き換えます。import.meta.env.VITE_* を参照してください。例:

    • const apiKey = "sk-abc123" → const apiKey = import.meta.env.VITE_API_KEY
    • const token = "eyJhbG..." → const token = import.meta.env.VITE_AUTH_TOKEN
  2. .env.example に変数を追加します。プレースホルダー値(例:VITE_API_KEY=your-api-key-here)を設定してください。ファイルが存在しない場合は作成してください。

  3. .env と .env.local が .gitignore に含まれていることを確認します。含まれていない場合は追加してください。

  4. CDF トークン、ユーザーオブジェクト、API キーを出力する console.log、console.error などの呼び出しを削除します。


Step 4 — 危険な DOM API を見つけて修正する

任意のスクリプト実行や HTML インジェクションを可能にするパターンを検索してください。

grep -rn --include="*.tsx" --include="*.ts" \
  -E "dangerouslySetInnerHTML|innerHTML\s*=|eval\(|new Function\(|setTimeout\(['\"]|setInterval\(['\"]" src/

危険な DOM パターンが見つかった場合は、それぞれ直接修正してください。必要に応じて pnpm add dompurify と pnpm add -D @types/dompurify を実行して DOMPurify をインストールしてください。

修正方法
  • dangerouslySetInnerHTML:値を DOMPurify.sanitize() でラップします。ファイルに import DOMPurify from 'dompurify' を追加します。例:

    // Before
    <div dangerouslySetInnerHTML={{ __html: userContent }} />
    // After
    import DOMPurify from 'dompurify';
    <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />
    
  • eval() / new Function():データ駆動型の方法に書き換えます。データの解析には JSON.parse() を使用し、動的なロジックの振り分けにはルックアップテーブルまたは switch 文を使用します。ユーザーが制御する文字列をコード評価に渡してはいけません。

  • 文字列引数を指定した setTimeout/setInterval:関数参照に変換します:

    // Before
    setTimeout("doSomething()", 1000)
    // After
    setTimeout(() => doSomething(), 1000)
    

ステップ 5 — 認証と認可の不備を見つけて修正する

認証の設定(おそらく src/contexts/、src/hooks/、または setup-dune-auth の出力)を確認します。

  • CDF データを表示するすべてのルートは、Dune 認証ガードの配下に置く必要があります(レンダリング前に useCogniteClient が null 以外の sdk を返すこと)。
  • CDF クライアントは、静的な API キーではなく、有効期間の短い OIDC トークンで初期化する必要があります。
  • ユーザーロール/機能のチェックはサーバー側(CDF ACL)で行う必要があります。UI 要素を非表示にすることだけに依存してはいけません。

useAtlasChat/Atlas エージェントの統合を確認します。

  • agentExternalId をユーザーが指定した入力から構築してはいけません。
  • ツールの execute 関数は args を無条件に信頼してはいけません。CDF クエリで値を使用する前に検証またはガードを行います。
修正方法

CDF データを表示する、認証ガードのないルートごとに、認証ガードコンポーネントでラップします。たとえば、useCogniteClient をチェックし、SDK の準備ができていない場合は読み込み状態またはログイン状態を表示するコンポーネントで、ルート要素がラップされていることを確認します。

Atlas ツールの execute 関数では、各関数の先頭に引数の検証を追加します。CDF クエリで値を使用する前に、各 args フィールドが想定された型であり、想定された範囲内であることを検証します。


ステップ 6 — 入力検証の不備を見つけて修正する

フォーム、URL パラメーター、またはクエリ文字列に由来する値は、CDF 呼び出しに渡す前、または DOM にレンダリングする前に、すべて検証する必要があります。

# Find useSearchParams, URLSearchParams, and form onChange handlers
grep -rn --include="*.tsx" --include="*.ts" \
  -E "useSearchParams|URLSearchParams|searchParams\.get|e\.target\.value" src/

検証されていない外部入力ごとに、実行時検証を追加します。Zod がインストールされていない場合は、インストールします(pnpm add zod)。想定される形状に一致するスキーマを作成し、型キャストではなく .safeParse() を使用します。

修正方法
  1. URL パラメーターとフォーム入力用の Zod スキーマを追加します。例:

    import { z } from 'zod';
    const paramSchema = z.object({
      id: z.string().min(1),
      page: z.coerce.number().int().positive().default(1),
    });
    const result = paramSchema.safeParse({ id: searchParams.get('id'), page: searchParams.get('page') });
    if (!result.success) { /* handle error */ }
    
  2. 外部データに対する as MyType キャストを Zod の .safeParse() に置き換えます。URL パラメーター、フォーム入力、API レスポンスのデータは、検証せずに信頼してはいけません。

  3. searchParams.get() に nullish フォールバックを追加します。パラメーターが存在しない場合や空の場合を必ず処理します。


ステップ 7 — Vite/サーバー設定の不備を見つけて修正する

vite.config.ts と、server.ts/express.ts ファイルがあればそれらを確認します。

修正方法

不足しているセキュリティヘッダーを vite.config.ts の server.headers セクションに追加します。セクションが存在しない場合は作成します。最低限必要なヘッダーは次のとおりです。

server: {
  headers: {
    'Content-Security-Policy': "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://*.cognitedata.com",
    'X-Frame-Options': 'DENY',
    'X-Content-Type-Options': 'nosniff',
  },
}

アプリの実際の要件に合わせて Content-Security-Policy を調整します(たとえば、フォントや画像用に特定の CDN ホストを追加します)。

また、以下も行います。

  • vite.config.ts で、シークレットをそのままバンドルに埋め込む define エントリーを削除します。代わりに import.meta.env を使用します。
  • 開発用プロキシ(server.proxy)が、本番ビルドで内部エンドポイントを公開しないことを確認します。

ステップ 8 — 依存関係の脆弱性を見つけて修正する

pnpm audit --audit-level=high
修正方法
  1. まず pnpm audit fix を実行し、可能な範囲で自動修正します。
  2. 高または重大な CVE が残っている場合は、package.json のパッケージバージョンを手動で更新し、pnpm install を実行します。
  3. 脆弱性のあるパッケージに修正がない場合は、既知のリスクとして記録し、代替パッケージがないか確認します。

ステップ 9 — 残っている指摘事項の報告

自動修正できなかった問題のみを報告してください(例:人による判断が必要なアーキテクチャ上の決定、利用可能な修正がないパッケージ、大幅なリファクタリングが必要なパターン)。

各ステップで修正した内容をまとめてください。

ステップ修正内容残っている問題
2 — CDF SDKN 件の生の呼び出しを SDK に移行(移行できなかったもの)
3 — 認証情報N 件のハードコードされたシークレットを環境変数に置き換え(人による判断が必要なもの)
4 — DOMN 件の危険なパターンをサニタイズ(リファクタリングが必要なもの)
5 — 認証保護されていない N 件のルートを保護(アーキテクチャ上の不足点)
6 — 検証N 件の入力に Zod スキーマを追加(カスタムロジックが必要なもの)
7 — Vite 設定N 件のセキュリティヘッダーを追加(CSP の調整が必要か)
8 — 依存関係脆弱性のある N 件のパッケージを修正(利用可能な修正がないもの)

デプロイ前にただちに対応する必要がある問題が残っている場合は、明示的に列挙してください。


完了

修正した内容を述べ、アプリのセキュリティが向上したことを確認してください。次回のデプロイ前に人による判断が必要な項目が残っている場合は、列挙してください。

コメント