security

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Security 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
    /
    src/App.tsx
    — entry point, routing, auth gating
  • vite.config.ts
    — dev server proxy, CORS, headers
  • package.json
    — list of third-party dependencies
  • 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,
    fetch
    , user form input)
  • All places where data is written back (CDF upsert,
    fetch
    POST/PUT/DELETE)

在进行任何检查前,请先阅读以下文件:
  • 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 — 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
undefined
bash
undefined

Find 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/
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

查找看起来像CDF端点的原始URL构造

grep -rn --include=".ts" --include=".tsx"
-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/

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"
undefined
grep -rn --include=".ts" --include=".tsx"
-E "(Authorization|api-key|apikey|x-api-key)" src/ | grep -v "node_modules"
undefined

How 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.
PatternAction
fetch()
or
axios
call to a CDF URL (
*.cognitedata.com
,
/api/v1/projects/*
)
Rewrite to use the Cognite SDK (
cognite.files.getDownloadUrls(...)
,
cognite.timeseries.retrieve(...)
,
client.instances.search(...)
, etc.)
Custom
Authorization
header with a CDF token
Remove — the SDK handles auth automatically
WebSocket connection to CDF endpointsRewrite to use SDK streaming methods
Proxy endpoint that forwards to CDF internallyRewrite the proxy to use the SDK internally
fetch()
to a non-CDF URL (static assets, documented third-party API)
Leave — but add a comment documenting why it's needed
After rewriting all CDF calls, remove any
axios
or
fetch
-related imports that are no longer used.
对于每个找到的原始CDF调用,阅读周边代码以了解其目标CDF资源和操作,然后使用合适的SDK方法重写。若原始HTTP客户端的导入不再使用,请将其移除。
模式操作
调用
fetch()
axios
访问CDF URL(
*.cognitedata.com
/api/v1/projects/*
重写为使用Cognite SDK(
cognite.files.getDownloadUrls(...)
cognite.timeseries.retrieve(...)
client.instances.search(...)
等)
自定义
Authorization
头携带CDF令牌
移除 — SDK会自动处理身份验证
与CDF端点建立WebSocket连接重写为使用SDK的流处理方法
内部转发至CDF的代理端点重写代理逻辑,使其内部使用SDK
fetch()
访问非CDF URL(静态资源、已文档化的第三方API)
保留 — 但需添加注释说明必要性
重写所有CDF调用后,移除任何不再使用的
axios
fetch
相关导入。

What is acceptable

可接受的情况

  • All CDF reads/writes through
    sdk.files.*
    ,
    sdk.timeseries.*
    ,
    client.instances.*
    , etc.
  • 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.*
    client.instances.*
    等SDK方法完成
  • 非CDF网络调用需满足:
    • 访问已知的静态资源主机(CDN、图片服务)
    • 访问产品所需的已文档化第三方API
    • 在应用的README或架构文档中有明确说明

Step 3 — Find and fix credential & secret hygiene

步骤3 — 查找并修复凭证与密钥管理问题

Search for hard-coded credentials and sensitive values:
bash
undefined
搜索硬编码的凭证和敏感值:
bash
undefined

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/

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/

对于每个硬编码的密钥,将其替换为环境变量。创建或更新`.env.example`文件,添加占位符。若`.gitignore`中缺少`.env`,请将其添加进去。

How to fix

修复方法

  1. Replace each hardcoded secret with an
    import.meta.env.VITE_*
    reference. For example:
    • const apiKey = "sk-abc123"
      const apiKey = import.meta.env.VITE_API_KEY
    • const token = "eyJhbG..."
      const token = import.meta.env.VITE_AUTH_TOKEN
  2. Add the variable to
    .env.example
    with a placeholder value (e.g.,
    VITE_API_KEY=your-api-key-here
    ). Create
    .env.example
    if it doesn't exist.
  3. Ensure
    .env
    and
    .env.local
    are in
    .gitignore
    — add them if missing.
  4. Remove any
    console.log
    ,
    console.error
    , or similar calls
    that print a CDF token, user object, or API key.

  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
    )。若
    .env.example
    不存在则创建该文件。
  3. 确保
    .env
    .env.local
    已在
    .gitignore
    — 若缺失则添加。
  4. 移除所有打印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
pnpm add dompurify
and
pnpm add -D @types/dompurify
if needed.
搜索允许任意脚本执行或HTML注入的模式:
bash
grep -rn --include="*.tsx" --include="*.ts" \
  -E "dangerouslySetInnerHTML|innerHTML\s*=|eval\(|new Function\(|setTimeout\(['\"]|setInterval\(['\"]" src/
对于每个危险DOM模式,直接应用修复。若需要,请安装DOMPurify:
pnpm add dompurify
pnpm add -D @types/dompurify

How to fix

修复方法

  • dangerouslySetInnerHTML
    : Wrap the value with
    DOMPurify.sanitize()
    . Add
    import DOMPurify from 'dompurify'
    to the file. Example:
    tsx
    // Before
    <div dangerouslySetInnerHTML={{ __html: userContent }} />
    // After
    import DOMPurify from 'dompurify';
    <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />
  • eval()
    /
    new Function()
    : Rewrite using a data-driven approach. Use
    JSON.parse()
    for data parsing, or a lookup table / switch statement for dynamic logic dispatch. Never pass user-controlled strings to code evaluation.
  • setTimeout
    /
    setInterval
    with a string argument
    : Convert to a function reference:
    ts
    // 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()
    :使用数据驱动的方式重写。使用
    JSON.parse()
    解析数据,或使用查找表/switch语句处理动态逻辑分发。绝不要将用户可控的字符串传入代码求值函数。
  • setTimeout
    /
    setInterval
    使用字符串参数
    :转换为函数引用:
    ts
    // 修复前
    setTimeout("doSomething()", 1000)
    // 修复后
    setTimeout(() => doSomething(), 1000)

Step 5 — Find and fix authentication & authorization gaps

步骤5 — 查找并修复身份验证与授权漏洞

Read the auth setup (likely
src/contexts/
,
src/hooks/
, or
setup-flows-auth
output):
  • Every route that shows CDF data must be behind the Flows auth guard (
    useCogniteClient
    returns a non-null
    sdk
    before rendering).
  • 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
useAtlasChat
/ Atlas agent integration:
  • The
    agentExternalId
    must not be constructed from user-supplied input.
  • Tool
    execute
    functions must not trust
    args
    blindly — validate or guard before using values in CDF queries.
阅读身份验证设置(通常位于
src/contexts/
src/hooks/
setup-flows-auth
输出中):
  • 所有展示CDF数据的路由必须受Flows权限校验保护(
    useCogniteClient
    返回非空
    sdk
    后再渲染)。
  • CDF客户端必须使用短期OIDC令牌初始化,而非静态API密钥。
  • 用户角色/权限检查必须在服务器端(CDF ACL)进行——不要仅依赖隐藏UI元素。
检查
useAtlasChat
/ Atlas agent集成:
  • agentExternalId
    不得由用户提供的输入构造。
  • Tool的
    execute
    函数不得盲目信任
    args
    ——在CDF查询中使用值之前必须进行验证或校验。

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
useCogniteClient
and renders a loading/login state when the SDK is not ready.
For Atlas tool
execute
functions, add argument validation at the top of each function. Validate that each
args
field is the expected type and within expected bounds before using it in any CDF query.

对于每个未受保护的展示CDF数据的路由,使用权限校验组件包裹。例如,确保路由元素被一个检查
useCogniteClient
的组件包裹,当SDK未就绪时渲染加载/登录状态。
对于Atlas tool的
execute
函数,在每个函数顶部添加参数验证。验证每个
args
字段是否为预期类型且在预期范围内,然后再将其用于任何CDF查询。

Step 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
undefined

Find useSearchParams, URLSearchParams, and form onChange handlers

查找useSearchParams、URLSearchParams及表单onChange处理函数

grep -rn --include=".tsx" --include=".ts"
-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/

对于每个未验证的外部输入,添加运行时验证。若未安装Zod,请执行`pnpm add zod`。创建匹配预期格式的schema,并使用`.safeParse()`而非类型转换。

How to fix

修复方法

  1. 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 */ }
  2. Replace
    as MyType
    casts on external data
    with Zod
    .safeParse()
    — never trust data from URL params, form inputs, or API responses without validation.
  3. Add nullish fallbacks for
    searchParams.get()
    — always handle the case where the param is missing or empty.

  1. 为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) { /* 处理错误 */ }
  2. 将外部数据的
    as MyType
    类型转换
    替换为Zod的
    .safeParse()
    ——绝不要信任来自URL参数、表单输入或API响应的数据,必须先验证。
  3. searchParams.get()
    添加空值回退
    ——始终处理参数缺失或为空的情况。

Step 7 — Find and fix Vite / server configuration

步骤7 — 查找并修复Vite / 服务器配置

Read
vite.config.ts
and any
server.ts
/
express.ts
files.
阅读
vite.config.ts
及所有
server.ts
/
express.ts
文件。

How to fix

修复方法

Add any missing security headers to the
vite.config.ts
server.headers
section. If the section doesn't exist, create it. The minimum required headers are:
ts
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
Content-Security-Policy
to match the app's actual needs (e.g., adding specific CDN hosts for fonts or images).
Also:
  • Remove any
    define
    entries
    in
    vite.config.ts
    that embed raw secrets into the bundle. Use
    import.meta.env
    instead.
  • Confirm the dev proxy (
    server.proxy
    ) does not expose internal endpoints in production builds.

vite.config.ts
server.headers
部分添加缺失的安全头。若该部分不存在则创建。最低要求的安全头如下:
ts
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
    )不会在生产构建中暴露内部端点。

Step 8 — Find and fix dependency vulnerabilities

步骤8 — 查找并修复依赖漏洞

bash
pnpm audit --audit-level=high
bash
pnpm audit --audit-level=high

How to fix

修复方法

  1. Run
    pnpm audit fix
    first to auto-fix what's possible.
  2. For any remaining high/critical CVEs, manually update the package version in
    package.json
    and run
    pnpm install
    .
  3. If a vulnerable package has no fix available, document it as a known risk and check if there's an alternative package.

  1. 首先运行
    pnpm audit fix
    自动修复可处理的问题。
  2. 对于剩余的高/严重级别CVE,手动更新
    package.json
    中的包版本并运行
    pnpm install
  3. 若存在无可用修复的漏洞包,将其记录为已知风险,并检查是否有替代包。

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:
StepWhat was fixedRemaining issues
2 — CDF SDKMigrated N raw calls to SDK(any that couldn't be migrated)
3 — CredentialsReplaced N hardcoded secrets with env vars(any that need human decision)
4 — DOMSanitized N dangerous patterns(any that need refactoring)
5 — AuthWrapped N unguarded routes(any architectural gaps)
6 — ValidationAdded Zod schemas to N inputs(any that need custom logic)
7 — Vite configAdded N security headers(any CSP tuning needed)
8 — DependenciesFixed 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.
说明已修复的内容,并确认应用的安全性已提升。列出所有在下次部署前需要人工判断的剩余事项。