security について
アプリケーションコードのセキュリティレビューと修正を支援するスキルです。CDF アクセス、認証情報、DOM、認証、入力検証、設定、依存関係を順に確認し、自動修正できない問題の報告も促します。
主な機能
- 01ルートとデータ入力箇所の把握
- 02生の CDF 通信を Cognite SDK に移行
- 03シークレットと危険な DOM パターンの確認
- 04認証と入力検証のレビュー
- 05Vite 設定と依存関係の確認
- 06修正内容と未解決事項の整理
活用シーン
- 01デプロイ前のアプリ監査
- 02生の CDF 通信の検出と修正
- 03認証情報、認証、ユーザー入力のレビュー
- 04セキュリティヘッダーと依存関係の脆弱性確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cognitedata/ builder-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 がない場合は追加してください。
修正方法
-
ハードコードされたシークレットをそれぞれ置き換えます。
import.meta.env.VITE_*を参照してください。例:const apiKey = "sk-abc123"→const apiKey = import.meta.env.VITE_API_KEYconst token = "eyJhbG..."→const token = import.meta.env.VITE_AUTH_TOKEN
-
.env.exampleに変数を追加します。プレースホルダー値(例:VITE_API_KEY=your-api-key-here)を設定してください。ファイルが存在しない場合は作成してください。 -
.envと.env.localが.gitignoreに含まれていることを確認します。含まれていない場合は追加してください。 -
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-flows-auth の出力が該当する可能性があります)。
- CDF データを表示するすべてのルートは、Flows の認証ガードの背後に配置する必要があります(レンダリング前に
useCogniteClientが null ではないsdkを返すこと)。 - CDF クライアントは、静的な API キーではなく、有効期間の短い OIDC トークンで初期化する必要があります。
- ユーザーのロール/権限のチェックはサーバー側(CDF ACL)で行う必要があります。UI 要素を非表示にするだけに頼らないでください。
Atlas/エージェントを確認します:
- EOS サイドバー(
integrate-fusion-agent)を優先します。アプリ内のuseAtlasChatは例外的な場合に限ります。 agentExternalIdをユーザー入力から取得しないでください。CDF クエリの前に、ツール/アクションの引数を検証します。- CDF データを使ったサードパーティ製 LLM API の利用は禁止です。クエリ結果に対して、上限のない補完を行わないでください(5 件/最大 50 件、キャッシュ済み)。
修正方法
CDF データを表示する認証ガードのないルートごとに、認証ガードコンポーネントでラップします。たとえば、ルート要素が useCogniteClient をチェックし、SDK の準備ができていない場合に読み込み中またはログイン状態を表示するコンポーネントでラップされていることを確認します。
Atlas ツールの execute 関数と Fusion エージェントのアクションハンドラーでは、各関数の先頭に引数の検証を追加します。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() を使用します。
修正方法
-
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 */ } -
外部データに対する
as MyTypeの型キャストを Zod の.safeParse()に置き換えます。URL パラメーター、フォーム入力、API レスポンスからのデータは、検証せずに信頼しないでください。 -
searchParams.get()に null 値へのフォールバックを追加します。パラメーターが存在しない、または空の場合も必ず処理してください。
ステップ 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
修正方法
- まず
pnpm audit fixを実行し、可能なものを自動修正します。 - 深刻度が高い、または重大な CVE が残っている場合は、
package.jsonのパッケージバージョンを手動で更新してからpnpm installを実行します。 - 脆弱なパッケージに修正がない場合は、既知のリスクとして記録し、代替パッケージがあるか確認します。
ステップ 9 — 残っている指摘事項の報告
自動修正できなかった問題のみを報告してください(例:人による判断が必要なアーキテクチャ上の決定、利用可能な修正がないパッケージ、大幅なリファクタリングが必要なパターン)。
各ステップで修正した内容をまとめてください。
| ステップ | 修正内容 | 残っている問題 |
|---|---|---|
| 2 — CDF SDK | N 件の生の呼び出しを SDK に移行 | (移行できなかったもの) |
| 3 — 認証情報 | N 件のハードコードされたシークレットを環境変数に置き換え | (人による判断が必要なもの) |
| 4 — DOM | N 件の危険なパターンをサニタイズ | (リファクタリングが必要なもの) |
| 5 — 認証 | 保護されていない N 件のルートを保護 | (アーキテクチャ上の不足点) |
| 6 — 検証 | N 件の入力に Zod スキーマを追加 | (カスタムロジックが必要なもの) |
| 7 — Vite 設定 | N 件のセキュリティヘッダーを追加 | (CSP の調整が必要か) |
| 8 — 依存関係 | 脆弱性のある N 件のパッケージを修正 | (利用可能な修正がないもの) |
デプロイ前にただちに対応する必要がある問題が残っている場合は、明示的に列挙してください。
完了
修正した内容を述べ、アプリのセキュリティが向上したことを確認してください。次回のデプロイ前に人による判断が必要な項目が残っている場合は、列挙してください。