security
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSecurity Fix
安全修复
Find and fix security issues in $ARGUMENTS (or the whole app if no argument is given). Work through every step below in order. Every step that finds an issue must also fix it.
在**$ARGUMENTS**中查找并修复安全问题(若未指定参数则检查整个应用)。请按顺序完成以下每一步。每一步中发现的问题都必须进行修复。
Step 1 — Map the attack surface
步骤1 — 梳理攻击面
Read these files before checking anything:
- /
src/main.tsx— entry point, routing, auth gatingsrc/App.tsx - — dev server proxy, CORS, headers
vite.config.ts - — list of third-party dependencies
package.json - Any file matching ,
**/auth*,**/login*,**/token***/credential*
Identify:
- All pages/routes and whether each is behind an auth guard
- All places where external data enters the app (CDF SDK calls, , user form input)
fetch - All places where data is written back (CDF upsert, POST/PUT/DELETE)
fetch
在进行任何检查前,请先阅读以下文件:
- /
src/main.tsx— 入口文件、路由、权限校验入口src/App.tsx - — 开发服务器代理、CORS、请求头
vite.config.ts - — 第三方依赖列表
package.json - 所有匹配、
**/auth*、**/login*、**/token*的文件**/credential*
识别以下内容:
- 所有页面/路由,以及每个路由是否受权限校验保护
- 外部数据进入应用的所有入口(CDF SDK调用、、用户表单输入)
fetch - 数据回写的所有位置(CDF upsert、POST/PUT/DELETE请求)
fetch
Step 2 — Migrate all CDF access to the Cognite SDK
步骤2 — 将所有CDF访问迁移至Cognite SDK
All traffic to Cognite Data Fusion (CDF) must go through the official Cognite SDK. Find any HTTP, WebSocket, or other network call to CDF-like hosts or APIs that bypasses the SDK and rewrite it to use the SDK.
所有与Cognite Data Fusion (CDF)的通信必须通过官方Cognite SDK进行。查找所有绕过SDK直接调用CDF类主机或API的HTTP、WebSocket或其他网络请求,并将其重写为使用SDK的方式。
Search for raw HTTP calls
搜索原始HTTP调用
bash
undefinedbash
undefinedFind fetch, axios, XMLHttpRequest, and other HTTP client usage
查找fetch、axios、XMLHttpRequest及其他HTTP客户端的使用
grep -rn --include=".ts" --include=".tsx" --include="*.js"
-E "(fetch(|axios.|axios(|XMLHttpRequest|.ajax(|http.get(|http.post(|request()" src/
-E "(fetch(|axios.|axios(|XMLHttpRequest|.ajax(|http.get(|http.post(|request()" src/
grep -rn --include=".ts" --include=".tsx" --include="*.js"
-E "(fetch(|axios.|axios(|XMLHttpRequest|.ajax(|http.get(|http.post(|request()" src/
-E "(fetch(|axios.|axios(|XMLHttpRequest|.ajax(|http.get(|http.post(|request()" src/
Find raw URL construction that looks like CDF endpoints
查找看起来像CDF端点的原始URL构造
grep -rn --include=".ts" --include=".tsx"
-E "(cognitedata.com|cognite.ai|/api/v1/projects|cdf.|.cognite.)" src/
-E "(cognitedata.com|cognite.ai|/api/v1/projects|cdf.|.cognite.)" src/
grep -rn --include=".ts" --include=".tsx"
-E "(cognitedata.com|cognite.ai|/api/v1/projects|cdf.|.cognite.)" src/
-E "(cognitedata.com|cognite.ai|/api/v1/projects|cdf.|.cognite.)" src/
Find custom Authorization or api-key headers
查找自定义Authorization或api-key请求头
grep -rn --include=".ts" --include=".tsx"
-E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
-E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
undefinedgrep -rn --include=".ts" --include=".tsx"
-E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
-E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
undefinedHow to fix
修复方法
For each raw CDF call found, read the surrounding code to understand what CDF resource and operation it targets, then rewrite it using the appropriate SDK method. Remove the raw HTTP client import if it's no longer used.
| Pattern | Action |
|---|---|
| Rewrite to use the Cognite SDK ( |
Custom | Remove — the SDK handles auth automatically |
| WebSocket connection to CDF endpoints | Rewrite to use SDK streaming methods |
| Proxy endpoint that forwards to CDF internally | Rewrite the proxy to use the SDK internally |
| Leave — but add a comment documenting why it's needed |
After rewriting all CDF calls, remove any or -related imports that are no longer used.
axiosfetch对于每个找到的原始CDF调用,阅读周边代码以了解其目标CDF资源和操作,然后使用合适的SDK方法重写。若原始HTTP客户端的导入不再使用,请将其移除。
| 模式 | 操作 |
|---|---|
调用 | 重写为使用Cognite SDK( |
自定义 | 移除 — SDK会自动处理身份验证 |
| 与CDF端点建立WebSocket连接 | 重写为使用SDK的流处理方法 |
| 内部转发至CDF的代理端点 | 重写代理逻辑,使其内部使用SDK |
| 保留 — 但需添加注释说明必要性 |
重写所有CDF调用后,移除任何不再使用的或相关导入。
axiosfetchWhat is acceptable
可接受的情况
- All CDF reads/writes through ,
sdk.files.*,sdk.timeseries.*, etc.client.instances.* - Non-CDF network calls that are:
- To known static asset hosts (CDNs, image services)
- To documented third-party APIs required by the product
- Explicitly noted in the app's README or architecture docs
- 所有CDF读写操作通过、
sdk.files.*、sdk.timeseries.*等SDK方法完成client.instances.* - 非CDF网络调用需满足:
- 访问已知的静态资源主机(CDN、图片服务)
- 访问产品所需的已文档化第三方API
- 在应用的README或架构文档中有明确说明
Step 3 — Find and fix credential & secret hygiene
步骤3 — 查找并修复凭证与密钥管理问题
Search for hard-coded credentials and sensitive values:
bash
undefined搜索硬编码的凭证和敏感值:
bash
undefinedLook 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/
-E "(password|secret|apikey|api_key|token|bearer|private_key)\s=\s*['"]" src/
For each hardcoded secret, replace it with an environment variable. Create or update `.env.example` with a placeholder. Add `.env` to `.gitignore` if missing.grep -rn --include=".ts" --include=".tsx" --include=".js"
-E "(password|secret|apikey|api_key|token|bearer|private_key)\s=\s*['"]" src/
-E "(password|secret|apikey|api_key|token|bearer|private_key)\s=\s*['"]" src/
对于每个硬编码的密钥,将其替换为环境变量。创建或更新`.env.example`文件,添加占位符。若`.gitignore`中缺少`.env`,请将其添加进去。How to fix
修复方法
-
Replace each hardcoded secret with anreference. For example:
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
-
Add the variable towith a placeholder value (e.g.,
.env.example). CreateVITE_API_KEY=your-api-key-hereif it doesn't exist..env.example -
Ensureand
.envare in.env.local— add them if missing..gitignore -
Remove any,
console.log, or similar calls that print a CDF token, user object, or API key.console.error
-
将每个硬编码密钥替换为引用。示例:
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
-
将变量添加至,并设置占位值(例如:
.env.example)。若VITE_API_KEY=your-api-key-here不存在则创建该文件。.env.example -
确保和
.env已在.env.local中 — 若缺失则添加。.gitignore -
移除所有打印CDF令牌、用户对象或API密钥的、
console.log等调用。console.error
Step 4 — Find and fix dangerous DOM APIs
步骤4 — 查找并修复危险DOM API使用
Search for patterns that allow arbitrary script execution or HTML injection:
bash
grep -rn --include="*.tsx" --include="*.ts" \
-E "dangerouslySetInnerHTML|innerHTML\s*=|eval\(|new Function\(|setTimeout\(['\"]|setInterval\(['\"]" src/For each dangerous DOM pattern, apply the fix directly. Install DOMPurify with and if needed.
pnpm add dompurifypnpm add -D @types/dompurify搜索允许任意脚本执行或HTML注入的模式:
bash
grep -rn --include="*.tsx" --include="*.ts" \
-E "dangerouslySetInnerHTML|innerHTML\s*=|eval\(|new Function\(|setTimeout\(['\"]|setInterval\(['\"]" src/对于每个危险DOM模式,直接应用修复。若需要,请安装DOMPurify:和。
pnpm add dompurifypnpm add -D @types/dompurifyHow to fix
修复方法
-
: Wrap the value with
dangerouslySetInnerHTML. AddDOMPurify.sanitize()to the file. Example:import DOMPurify from 'dompurify'tsx// Before <div dangerouslySetInnerHTML={{ __html: userContent }} /> // After import DOMPurify from 'dompurify'; <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} /> -
/
eval(): Rewrite using a data-driven approach. Usenew Function()for data parsing, or a lookup table / switch statement for dynamic logic dispatch. Never pass user-controlled strings to code evaluation.JSON.parse() -
/
setTimeoutwith a string argument: Convert to a function reference:setIntervalts// Before setTimeout("doSomething()", 1000) // After setTimeout(() => doSomething(), 1000)
-
:使用
dangerouslySetInnerHTML包裹值。在文件中添加DOMPurify.sanitize()。示例:import DOMPurify from 'dompurify'tsx// 修复前 <div dangerouslySetInnerHTML={{ __html: userContent }} /> // 修复后 import DOMPurify from 'dompurify'; <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} /> -
/
eval():使用数据驱动的方式重写。使用new Function()解析数据,或使用查找表/switch语句处理动态逻辑分发。绝不要将用户可控的字符串传入代码求值函数。JSON.parse() -
/
setTimeout使用字符串参数:转换为函数引用:setIntervalts// 修复前 setTimeout("doSomething()", 1000) // 修复后 setTimeout(() => doSomething(), 1000)
Step 5 — Find and fix authentication & authorization gaps
步骤5 — 查找并修复身份验证与授权漏洞
Read the auth setup (likely , , or output):
src/contexts/src/hooks/setup-flows-auth- Every route that shows CDF data must be behind the Flows auth guard (returns a non-null
useCogniteClientbefore rendering).sdk - The CDF client must be initialized with short-lived OIDC tokens, not a static API key.
- User role/capability checks must happen server-side (CDF ACLs) — do not rely solely on hiding UI elements.
Check the / Atlas agent integration:
useAtlasChat- The must not be constructed from user-supplied input.
agentExternalId - Tool functions must not trust
executeblindly — validate or guard before using values in CDF queries.args
阅读身份验证设置(通常位于、或输出中):
src/contexts/src/hooks/setup-flows-auth- 所有展示CDF数据的路由必须受Flows权限校验保护(返回非空
useCogniteClient后再渲染)。sdk - CDF客户端必须使用短期OIDC令牌初始化,而非静态API密钥。
- 用户角色/权限检查必须在服务器端(CDF ACL)进行——不要仅依赖隐藏UI元素。
检查 / Atlas agent集成:
useAtlasChat- 不得由用户提供的输入构造。
agentExternalId - Tool的函数不得盲目信任
execute——在CDF查询中使用值之前必须进行验证或校验。args
How to fix
修复方法
For each unguarded route that shows CDF data, wrap it with the auth guard component. For example, ensure the route element is wrapped in a component that checks and renders a loading/login state when the SDK is not ready.
useCogniteClientFor Atlas tool functions, add argument validation at the top of each function. Validate that each field is the expected type and within expected bounds before using it in any CDF query.
executeargs对于每个未受保护的展示CDF数据的路由,使用权限校验组件包裹。例如,确保路由元素被一个检查的组件包裹,当SDK未就绪时渲染加载/登录状态。
useCogniteClient对于Atlas tool的函数,在每个函数顶部添加参数验证。验证每个字段是否为预期类型且在预期范围内,然后再将其用于任何CDF查询。
executeargsStep 6 — Find and fix input validation gaps
步骤6 — 查找并修复输入验证漏洞
Every value that comes from a form, URL param, or query string before it reaches a CDF call or is rendered to the DOM must be validated:
bash
undefined所有来自表单、URL参数或查询字符串的值,在传入CDF调用或渲染至DOM之前必须经过验证:
bash
undefinedFind useSearchParams, URLSearchParams, and form onChange handlers
查找useSearchParams、URLSearchParams及表单onChange处理函数
grep -rn --include=".tsx" --include=".ts"
-E "useSearchParams|URLSearchParams|searchParams.get|e.target.value" src/
-E "useSearchParams|URLSearchParams|searchParams.get|e.target.value" src/
For each unvalidated external input, add runtime validation. Install Zod if not present (`pnpm add zod`). Create a schema that matches the expected shape and use `.safeParse()` instead of type casts.grep -rn --include=".tsx" --include=".ts"
-E "useSearchParams|URLSearchParams|searchParams.get|e.target.value" src/
-E "useSearchParams|URLSearchParams|searchParams.get|e.target.value" src/
对于每个未验证的外部输入,添加运行时验证。若未安装Zod,请执行`pnpm add zod`。创建匹配预期格式的schema,并使用`.safeParse()`而非类型转换。How to fix
修复方法
-
Add Zod schemas for URL params and form inputs. Example:ts
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 */ } -
Replacecasts on external data with Zod
as MyType— never trust data from URL params, form inputs, or API responses without validation..safeParse() -
Add nullish fallbacks for— always handle the case where the param is missing or empty.
searchParams.get()
-
为URL参数和表单输入添加Zod schema。示例:ts
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) { /* 处理错误 */ } -
将外部数据的类型转换替换为Zod的
as MyType——绝不要信任来自URL参数、表单输入或API响应的数据,必须先验证。.safeParse() -
为添加空值回退——始终处理参数缺失或为空的情况。
searchParams.get()
Step 7 — Find and fix Vite / server configuration
步骤7 — 查找并修复Vite / 服务器配置
Read and any / files.
vite.config.tsserver.tsexpress.ts阅读及所有 / 文件。
vite.config.tsserver.tsexpress.tsHow to fix
修复方法
Add any missing security headers to the section. If the section doesn't exist, create it. The minimum required headers are:
vite.config.tsserver.headersts
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',
},
}Adjust the to match the app's actual needs (e.g., adding specific CDN hosts for fonts or images).
Content-Security-PolicyAlso:
- Remove any entries in
definethat embed raw secrets into the bundle. Usevite.config.tsinstead.import.meta.env - Confirm the dev proxy () does not expose internal endpoints in production builds.
server.proxy
在的部分添加缺失的安全头。若该部分不存在则创建。最低要求的安全头如下:
vite.config.tsserver.headersts
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',
},
}根据应用的实际需求调整(例如,为字体或图片添加特定CDN主机)。
Content-Security-Policy此外:
- 移除中任何将原始密钥嵌入打包文件的
vite.config.ts配置。改用define。import.meta.env - 确认开发代理()不会在生产构建中暴露内部端点。
server.proxy
Step 8 — Find and fix dependency vulnerabilities
步骤8 — 查找并修复依赖漏洞
bash
pnpm audit --audit-level=highbash
pnpm audit --audit-level=highHow to fix
修复方法
- Run first to auto-fix what's possible.
pnpm audit fix - For any remaining high/critical CVEs, manually update the package version in and run
package.json.pnpm install - If a vulnerable package has no fix available, document it as a known risk and check if there's an alternative package.
- 首先运行自动修复可处理的问题。
pnpm audit fix - 对于剩余的高/严重级别CVE,手动更新中的包版本并运行
package.json。pnpm install - 若存在无可用修复的漏洞包,将其记录为已知风险,并检查是否有替代包。
Step 9 — Report remaining findings
步骤9 — 报告剩余问题
Report only issues that could not be auto-fixed (e.g., architectural decisions that need human judgment, packages with no available fix, or patterns that require significant refactoring).
Summarize what was fixed in each step:
| Step | What was fixed | Remaining issues |
|---|---|---|
| 2 — CDF SDK | Migrated N raw calls to SDK | (any that couldn't be migrated) |
| 3 — Credentials | Replaced N hardcoded secrets with env vars | (any that need human decision) |
| 4 — DOM | Sanitized N dangerous patterns | (any that need refactoring) |
| 5 — Auth | Wrapped N unguarded routes | (any architectural gaps) |
| 6 — Validation | Added Zod schemas to N inputs | (any that need custom logic) |
| 7 — Vite config | Added N security headers | (any CSP tuning needed) |
| 8 — Dependencies | Fixed N vulnerable packages | (any with no available fix) |
If any remaining issues require immediate action before deployment, list them explicitly.
仅报告无法自动修复的问题(例如,需要人工判断的架构决策、无可用修复的包、或需要大量重构的模式)。
总结每一步中已修复的内容:
| 步骤 | 已修复内容 | 剩余问题 |
|---|---|---|
| 2 — CDF SDK | 将N个原始调用迁移至SDK | (无法迁移的调用) |
| 3 — 凭证管理 | 将N个硬编码密钥替换为环境变量 | (需要人工决策的内容) |
| 4 — DOM安全 | 对N个危险模式进行了 sanitize 处理 | (需要重构的内容) |
| 5 — 权限校验 | 包裹了N个未受保护的路由 | (架构层面的漏洞) |
| 6 — 输入验证 | 为N个输入添加了Zod schema | (需要自定义逻辑的内容) |
| 7 — Vite配置 | 添加了N个安全头 | (需要调整CSP的内容) |
| 8 — 依赖管理 | 修复了N个漏洞包 | (无可用修复的包) |
若任何剩余问题需要在部署前立即处理,请明确列出。
Done
完成
State what was fixed and confirm the app is more secure. List any remaining items that require human judgment before the next deployment.
说明已修复的内容,并确认应用的安全性已提升。列出所有在下次部署前需要人工判断的剩余事项。