Back to skill

Security audit

zion-xhs-catch-skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Xiaohongshu scraping and reporting tool, but it combines logged-in browser automation, unverified remote installer execution, plaintext credential storage, external uploads, and silent sibling-project credential reuse.

Review before installing. Use only an isolated browser profile and non-critical Xiaohongshu account, avoid running the remote installer pipeline unless you independently trust and verify it, do not sync sensitive or private scraped data, and remove or fix the sibling credential fallback and plaintext secret storage before using Howtone/Zion sync.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/webbridge-crawl.ts:74
Finding
Automatic Execution of an Unverified Remote Installer<![CDATA[ ## Vulnerability Details **File Location**: `scripts/webbridge-crawl.ts:74-89`; also documented in `SKILL.md:33-40` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```typescript // 1. Check if executable exists if (!fs.existsSync(wbPath)) { console.log('🔍 未检测到 Kimi WebBridge 安装,正在为您自动下载并安装...'); try { if (isWin) { execSync('powershell -Command "irm https://cdn.kimi.com/webbridge/install.ps1 | iex"', { stdio: 'inherit' }); } else { execSync('curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash', { stdio: 'inherit' }); } console.log('✅ Kimi WebBridge 安装成功!'); } catch (err) { console.error('❌ 自动安装失败,请手动执行以下安装命令:'); if (isWin) { console.error(' irm https://cdn.kimi.com/webbridge/install.ps1 | iex'); } else { console.error(' curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash'); } return false; } } ``` The documentation also directs users to execute mutable remote content: ```bash curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash ``` ```powershell irm https://cdn.kimi.com/webbridge/install.ps1 | iex ``` ### Technical Analysis When WebBridge is absent, the crawler automatically downloads a shell or PowerShell script and immediately executes it. The downloaded content is not pinned to a version and is not authenticated through a published checksum or cryptographic signature. The user is not shown the payload or asked for confirmation before execution. The remote installer is not part of the reviewed project, so its effective behavior can change after this audit. Although the hostname appears associated with the declared Kimi dependency, hostname trust does not protect against server compromise, malicious deployment, DNS compromise, or a compromised TLS trust chain. Installing WebBridge may be necessary for the declared browser-control functionality, but downloading and directly executing mutable ...[truncated 975 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic `curl | bash` and `irm | iex` execution. 2. Require the user to install WebBridge separately through a trusted package manager or signed release. 3. Pin an exact installer or binary version rather than retrieving a mutable endpoint. 4. Download the artifact to a local file and verify a published SHA-256 checksum and cryptographic signature before execution. 5. Display the source, version, destination, and requested actions, then require explicit user confirmation. 6. Run the installer with the lowest possible privileges and reject attempts to request unnecessary elevation. 7. Document how users can inspect, upgrade, and uninstall the dependency. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate-report.ts:225
Finding
Stored Cross-Site Scripting in Generated HTML Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-report.ts:61, 193-216, 225-289` **Vulnerability Type**: Stored cross-site scripting and unsafe JavaScript-context serialization **Risk Level**: High ### Vulnerable Code ```typescript const jsonData = JSON.stringify(data, null, 2); ``` ```html <script> const allData = ${jsonData}; function renderCards(data) { const container = document.getElementById('cards'); if (data.length === 0) { container.innerHTML = '<div class="empty-state">没有找到匹配的内容</div>'; return; } container.innerHTML = data.map((item, idx) => ` <div class="card" data-keyword="${item.keyword || ''}"> ${item.images && item.images.length ? ` <div class="card-images"> ${item.images.slice(0, 3).map(img => `<img src="${img}" alt="" loading="lazy">`).join('')} </div> ` : ''} <div class="card-content"> <span class="card-keyword">#${item.keyword || ''}</span> <div class="card-title">${item.title || '无标题'}</div> <div class="card-text">${item.content || ''}</div> <div class="card-meta"> <span class="card-author">${item.author_name || '匿名'}</span> </div> ${item.comments && item.comments.length ? ` <div class="comments-section"> <button class="comments-toggle" onclick="toggleComments(${idx})"> 💬 查看 ${item.comments.length} 条评论 </button> <div class="comments-list" id="comments-${idx}"> ${item.comments.map(c => ` <div class="comment-item"> <div class="comment-author">${c.author}</div> <div class="comment-content">${c.content}</div> </div> `).join('')} </div> </div> ` : ''} </div> </div> `).join(''); } ``` The pain-point view repeats the unsafe rend ...[truncated 2074 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not render untrusted content with `innerHTML`. 2. Build DOM elements with `document.createElement()` and assign untrusted values through `textContent`. 3. Validate image URLs and permit only expected HTTPS schemes and trusted image hosts. 4. If data must be embedded in a script, escape at least `<`, `>`, `&`, Unicode line separators, and script-closing sequences, or place encoded JSON in a non-executable data element. 5. Consider loading the JSON separately rather than interpolating it into an executable script. 6. Add a restrictive Content Security Policy that blocks inline scripts and limits outbound connections and image sources. 7. Add regression tests using payloads containing HTML tags, event handlers, quotes, template-literal syntax, and `</script>`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync.ts:37
Finding
Arbitrary URL Fetching Followed by Public Re-Upload<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync.ts:37-98, 214-223` **Vulnerability Type**: Server-side request forgery, unbounded download, and unintended public data exposure **Risk Level**: High ### Vulnerable Code ```typescript async function uploadImage(url: string, config: ZionConfig): Promise<string | null> { try { const resp = await fetch(url); if (!resp.ok) throw new Error(`HTTP ${resp.status}`); const buffer = Buffer.from(await resp.arrayBuffer()); const md5 = crypto.createHash('md5').update(buffer).digest('base64'); let suffix = 'JPG'; if (url.toLowerCase().endsWith('.png')) suffix = 'PNG'; else if (url.toLowerCase().endsWith('.webp')) suffix = 'WEBP'; else if (url.toLowerCase().endsWith('.gif')) suffix = 'GIF'; const gql = { query: ` mutation GetImageUploadUrl($md5: String!, $suffix: MediaFormat!) { imagePresignedUrl(imgMd5Base64: $md5, imageSuffix: $suffix, acl: PUBLIC_READ) { imageId uploadUrl uploadHeaders } } `, variables: { md5, suffix }, }; const res = await fetch(config.endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${config.token}`, }, body: JSON.stringify(gql), }); const json = await res.json(); if (json.errors) throw new Error(JSON.stringify(json.errors)); const { imageId, uploadUrl, uploadHeaders } = json.data.imagePresignedUrl; const headers: Record<string, string> = { 'Content-Type': resp.headers.get('content-type') || 'image/jpeg', }; if (uploadHeaders) { if (Array.isArray(uploadHeaders)) { uploadHeaders.forEach((h: any) => { headers[h.key] = h.value; }); } else { Object.entries(uploadHeaders).forEach(([k, v]) => { headers[k] = v as string; }); } } const putRes = await fetch( ...[truncated 2505 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only HTTPS URLs from an explicit allowlist of expected Xiaohongshu image hosts. 2. Resolve hostnames and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6. 3. Repeat address and hostname validation after every redirect, or disable redirects. 4. Reject URLs containing embedded credentials or unsupported ports. 5. Enforce strict connection, response, and total-operation timeouts. 6. Stream responses with a conservative byte limit instead of buffering arbitrary response bodies. 7. Validate both the declared MIME type and actual image-file signature. 8. Use private object ACLs unless public access is an explicit and informed user choice. 9. Display the destination, data scope, and visibility before upload and require confirmation. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/sync.ts:141
Finding
Silent Reuse of Administrative Credentials from a Sibling Project<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync.ts:141-159` **Vulnerability Type**: Cross-project credential access and least-privilege violation **Risk Level**: High ### Vulnerable Code ```typescript function loadConfig(): ZionConfig { const zionCredPath = path.resolve(process.cwd(), '.zion', 'credentials.yaml'); const siblingZionCredPath = path.resolve(process.cwd(), '..', 'pain-catcher', '.zion', 'credentials.yaml'); let credPath = fs.existsSync(zionCredPath) ? zionCredPath : (fs.existsSync(siblingZionCredPath) ? siblingZionCredPath : null); if (credPath) { const cred = parseYaml(fs.readFileSync(credPath, 'utf-8')); const projectExId = cred.project?.exId || cred.project?.exid || 'rmLyJ0ZJXK8'; const token = cred.project?.admin_token?.token || cred.admin_token?.token; const userId = cred.account?.user_id || cred.account?.userId || ''; if (projectExId && token) { return { endpoint: `https://zion-app.functorz.com/zero/${projectExId}/api/graphql-v2`, token, tableName: 'articles', userId, }; } } throw new Error('未找到有效 Zion 配置,请检查 .zion/credentials.yaml'); } ``` ### Technical Analysis If the current working directory does not contain Zion credentials, the script silently searches `../pain-catcher/.zion/credentials.yaml`. It then extracts and uses an administrative bearer token from that unrelated project. This behavior crosses a project boundary and is not necessary for the declared synchronization function. It is also not disclosed in the Skill’s usage instructions. The selected endpoint is derived from the sibling credential file, so data can be written under another project’s authority without explicit confirmation. The use of an `admin_token` further violates least privilege because synchronization should require only narrowly scoped insert and image-upload permissions. ### Attack Path 1. The user runs synchronization without a local `.zion/credentials ...[truncated 850 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the fallback to `../pain-catcher/.zion/credentials.yaml`. 2. Require credentials to be supplied through an explicit, user-selected configuration path. 3. Display and confirm the target project identifier and endpoint before synchronization. 4. Replace administrative tokens with narrowly scoped credentials that can only insert or update the required table and request private image uploads. 5. Reject ambiguous or missing project identifiers instead of using a hardcoded default. 6. Record the selected credential source without printing secret values. 7. Add tests ensuring the Skill never searches parent or sibling project directories. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/zion-login.ts:57
Finding
Browser Cookies and Administrative Tokens Stored in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `scripts/login.ts:68-71`; `scripts/zion-login.ts:57-70` **Vulnerability Type**: Insecure storage and handling of authentication material **Risk Level**: Medium ### Vulnerable Code Complete browser cookie storage: ```typescript async function saveCookies(context: BrowserContext) { const cookies = await context.cookies(); fs.writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2)); } ``` Administrative token storage: ```typescript const newCreds = ` project: exId: "${PROJECT_EX_ID}" admin_token: token: "${token}" expiry: "${expiryDate}" account: username: "${username}" user_id: "${userId}" `; fs.writeFileSync(CRED_PATH, newCreds.trim()); console.log(`✅ 同步 Token 保存成功!`); console.log(`🚀 弦外 Overtone 已就绪,准备好捕获商机了吗?`); console.log(`✨ 凭据已保存到: ${CRED_PATH}`); ``` The token is also accepted through a command-line argument: ```typescript const args = process.argv.slice(2); const token = args.find(a => a.startsWith('--token='))?.split('=')[1]; ``` ### Technical Analysis `login.ts` writes the complete Playwright cookie set to `cookies.json`, potentially including reusable session cookies. `zion-login.ts` writes an administrative bearer token to a plaintext YAML file. Neither write operation specifies restrictive file permissions. On systems with permissive process umasks, these files may be readable by other local users. They may also be captured by backups, development tools, support bundles, or accidental version-control commits. Passing the bearer token through `--token=...` can expose it in shell history and, depending on the operating system, process listings. Persisting Xiaohongshu cookies is also unnecessary for the WebBridge crawler shown in this project because that crawler controls an already logged-in real browser and does not read `cookies.json`. ### Attack Path 1. The user runs `login.ts` or `zion-login.ts`. 2. Reusable cookies or an administrative token are written to pl ...[truncated 731 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove cookie persistence if it is not used by the WebBridge workflow. 2. Store secrets in an operating-system credential manager rather than plaintext project files. 3. If file storage is unavoidable, create the directory with mode `0700` and files with mode `0600`, then verify permissions after creation. 4. Accept tokens through protected standard input or an interactive hidden prompt instead of command-line arguments. 5. Use short-lived, narrowly scoped synchronization tokens rather than administrative credentials. 6. Add the credential directory and cookie files to version-control ignore rules. 7. Document retention, rotation, revocation, and secure deletion procedures. 8. Avoid saving cookies after a timeout when successful authentication has not been confirmed. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description omits that it accepts sync tokens, parses JWTs, creates local credential files, and configures external authentication state. That mismatch is security-relevant because token and identity handling requires a much higher trust level than ordinary content collection and reporting.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description omits that it accepts sync tokens, parses JWTs, creates local credential files, and configures external authentication state. That mismatch is security-relevant because token and identity handling requires a much higher trust level than ordinary content collection and reporting.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description omits that it accepts sync tokens, parses JWTs, creates local credential files, and configures external authentication state. That mismatch is security-relevant because token and identity handling requires a much higher trust level than ordinary content collection and reporting.

External Script Fetching

High
Category
Supply Chain
Content
- **Mac / Linux 用户**:
  直接在终端运行以下命令:
  ```bash
  curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash
  ```
- **Windows 用户**:
  在 PowerShell 中运行以下命令:
Confidence
98% confidence
Finding
The documentation tells users to fetch and immediately execute a remote shell script via `curl ... | bash`. This is a classic arbitrary code execution and supply-chain risk: if the remote server, CDN, DNS path, or script content is compromised, the operator will run attacker-controlled code on their machine with their user privileges.

Chaining Abuse

High
Category
Tool Misuse
Content
- **Mac / Linux 用户**:
  直接在终端运行以下命令:
  ```bash
  curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash
  ```
- **Windows 用户**:
  在 PowerShell 中运行以下命令:
Confidence
98% confidence
Finding
The `| bash` pattern explicitly chains network retrieval into immediate execution, removing any review or integrity-verification step. In a skill that already requests browser control and authenticated sessions, this materially heightens the chance of full host compromise and subsequent theft of cookies, tokens, and local data.

Ae1

High
Category
analysis-evasion
Content
| `webbridge-crawl.ts` | 通过 WebBridge 控制用户真实浏览器采集 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| `zion-login.ts` | 保存「好痛 Howtone」项目同步 Token |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ssd 3

High
Confidence
93% confidence
Finding
The skill instructs users to save a synchronization token and upload collected data, including images, to an external platform. This is high risk because it combines credential handling with bulk exfiltration of harvested content to a third party, and the documentation does not clearly define trust, storage, retention, or access controls.

Ae1

High
Category
analysis-evasion
Content
| `sync.ts` | 将采集数据同步到「好痛 Howtone」项目(含图片上传) |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ssd 3

High
Confidence
94% confidence
Finding
The optional Howtone workflow asks the user to provide a sync token and send output files for external analysis, creating a clear channel for credential use and outbound data transfer. In the context of scraped, possibly account-derived content, this materially increases data leakage, compliance, and unauthorized-sharing risk.

Credential Access

High
Category
Privilege Escalation
Content
}

function loadConfig(): ZionConfig {
  const zionCredPath = path.resolve(process.cwd(), '.zion', 'credentials.yaml');
  const siblingZionCredPath = path.resolve(process.cwd(), '..', 'pain-catcher', '.zion', 'credentials.yaml');
  
  let credPath = fs.existsSync(zionCredPath) ? zionCredPath : (fs.existsSync(siblingZionCredPath) ? siblingZionCredPath : null);
Confidence
97% confidence
Finding
The code probes a predictable local path for `.zion/credentials.yaml`, indicating credential access behavior. In an agent skill, accessing stored credentials for a separate service materially increases risk because it can leverage existing admin tokens to perform authenticated actions beyond the user's expectation for a note-collection tool.

Credential Access

High
Category
Privilege Escalation
Content
function loadConfig(): ZionConfig {
  const zionCredPath = path.resolve(process.cwd(), '.zion', 'credentials.yaml');
  const siblingZionCredPath = path.resolve(process.cwd(), '..', 'pain-catcher', '.zion', 'credentials.yaml');
  
  let credPath = fs.existsSync(zionCredPath) ? zionCredPath : (fs.existsSync(siblingZionCredPath) ? siblingZionCredPath : null);
Confidence
98% confidence
Finding
The code also searches a sibling project directory (`../pain-catcher/.zion/credentials.yaml`) for credentials, broadening secret discovery beyond the current workspace. This increases the likelihood of unauthorized credential use and resembles lateral secret harvesting from adjacent projects.

Credential Access

High
Category
Privilege Escalation
Content
}
  }

  throw new Error('未找到有效 Zion 配置,请检查 .zion/credentials.yaml');
}

function buildInsertMutation(tableName: string, note: XHSNote, imageIds: string[], userId?: string): { query: string; variables: Record<string, any> } {
Confidence
91% confidence
Finding
Although this line is only an error message, it confirms to users and reviewers that the script expects and targets `.zion/credentials.yaml` for credential access. That reinforces the credential-access behavior but is not independently as severe as the actual file reads on lines 141-142.

Missing User Warnings

High
Confidence
98% confidence
Finding
The crawler performs remote installation automatically and without prior user approval, violating the principle of least surprise and removing an important safety checkpoint before executing privileged code. In a skill that already interacts with a real logged-in browser, silent installation substantially increases the chance of unwanted persistence or host compromise.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
Piping a remote script directly into `bash`/PowerShell executes unverified code from the network with the user's privileges, enabling full system compromise if the CDN, DNS, TLS path, or upstream publisher is compromised. This is especially severe here because the skill also expects access to a logged-in browser session, so compromise could expose local data, browser context, and authenticated accounts.

External Script Fetching

High
Category
Supply Chain
Content
if (isWin) {
        execSync('powershell -Command "irm https://cdn.kimi.com/webbridge/install.ps1 | iex"', { stdio: 'inherit' });
      } else {
        execSync('curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash', { stdio: 'inherit' });
      }
      console.log('✅ Kimi WebBridge 安装成功!');
    } catch (err) {
Confidence
99% confidence
Finding
Fetching an installer script over the network and piping it directly to `bash` is a classic remote code execution pattern with no integrity validation. Within this skill's context, it is especially dangerous because the resulting installed component can control the user's browser and access authenticated browsing activity.

External Script Fetching

High
Category
Supply Chain
Content
if (isWin) {
        console.error('   irm https://cdn.kimi.com/webbridge/install.ps1 | iex');
      } else {
        console.error('   curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash');
      }
      return false;
    }
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Credential Access

High
Category
Privilege Escalation
Content
/**
 * Zion 凭证保存脚本
 * 直接接收用户提供的「好痛 Howtone」同步 Token,并保存到 .zion/credentials.yaml
 * 
 * 用法:
 *   npx ts-node zion-login.ts --token="你的同步Token"
Confidence
96% confidence
Finding
The script explicitly instructs the user to provide a synchronization token and persists it as credential material, which is direct credential handling. In the context of a scraping skill, this is more sensitive because the token is unrelated to basic collection and may grant access to an external analysis platform if stolen.

Credential Access

High
Category
Privilege Escalation
Content
import * as path from 'path';

const PROJECT_EX_ID = 'rmLyJ0ZJXK8';
const CRED_PATH = path.resolve(process.cwd(), '.zion', 'credentials.yaml');

function decodeJwt(token: string): any {
  try {
Confidence
98% confidence
Finding
The code defines a fixed path for `credentials.yaml` under the current working directory and later stores the token there in plaintext-like form, creating a stable target for theft. A predictable credential file in a workspace increases the chance of accidental exposure through local compromise, repository inclusion, shared directories, or support bundles.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares powerful capabilities such as shell, network, and environment access but does not restrict or document tool scope. In a skill that automates browser actions, installs software, stores tokens, and uploads data externally, missing explicit permission boundaries increases the chance of overreach, unintended execution, or abuse by downstream prompts.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are broad enough to activate during ordinary discussion about Xiaohongshu, research, or content topics. Over-broad activation is risky for a skill with shell, network, login, scraping, and upload behaviors because it can cause the agent to enter a sensitive workflow without sufficiently explicit user intent.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The description does not prominently disclose the privacy, account, and third-party transmission implications of scraping logged-in content and synchronizing outputs to an external platform. In this context, omission is dangerous because the workflow handles user/account-derived data and may expose it outside the original platform.

Ssd 3

Medium
Confidence
87% confidence
Finding
The skill directly instructs collection of account-derived browsing data and comments, then offers synchronization to a third-party analysis platform. This is sensitive because logged-in browsing context and user-generated content may include personal data, and the transfer broadens exposure beyond the original source platform.

Ssd 3

Medium
Confidence
90% confidence
Finding
The instructions require the operator to remain logged into a real platform account while automation drives the browser to collect data. That raises both account-security and privacy risk because session-backed access is more sensitive than public browsing, and automation against a live session can expose private state, cookies, and platform-enforcement consequences.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Using `npx ts-node` without pinning exact package versions makes execution dependent on whatever version resolves at runtime. That creates supply-chain and reproducibility risk, especially in a skill that handles authenticated sessions and may access local files or external services.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/webbridge-crawl.ts:27