Back to skill

Security audit

News Briefing

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its implementation exposes users to command-injection and credential-handling risks when generating and sending news briefings.

Review before installing. Use this only with trusted operators and trusted input values, avoid untrusted topics/titles/target-user values, and do not provide production Feishu credentials until the scripts are changed to use fetch or execFile/spawn with argument arrays, validate inputs and links, keep secrets out of command strings, and require confirmation before sending real Feishu messages.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/news-digest.mjs:75
Finding

Shell Command Injection in News Orchestration

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch-news.mjs:41
Finding

Shell Command Injection in External API Requests

Content
View full analysis
`-H "${k}: ${v}"`).join(' '); const proxyArg = proxy ? `--proxy ${proxy}` : ''; const escaped = JSON.stringify(body).replace(/'/g, "'\\''"); const cmd = `curl -s --max-time ${Math.floor(timeoutMs / 1000)} ${proxyArg} -X POST "${url}" ${headerArgs} -d '${escaped}'`; return JSON.parse(execSync(cmd, { timeout: timeoutMs + 2000 }).toString()); } ``` ```js const escaped = JSON.stringify({ model: 'pa/claude-haiku-4-5-20251001', messages: [{ role: 'user', content: prompt }], max_tokens: 400, }).replace(/'/g, "'\\''"); const proxyArg = proxy ? `--proxy ${proxy}` : ''; const cmd = `curl -s --max-time 20 ${proxyArg} -X POST "https://api.ppinfra.com/v3/openai/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer ${ppioKey}" -d '${escaped}'`; const data = JSON.parse(execSync(cmd, { timeout: 22000 }).toString()); ``` ### Technical Analysis The script uses `execSync()` with dynamically constructed curl command strings. This unnecessarily places API requests behind a shell interpreter. The proxy value is read from `HTTPS_PROXY` or `https_proxy` and inserted without quoting: ```js const proxy = process.env.HTTPS_PROXY || process.env.https_proxy || ''; ``` The Perplexity and PPIO API keys are inserted into double-quoted header arguments. Shell command substitutions remain active inside double quotes. Thus, a malicious or compromised proxy or credential environment value can alter the command or cause a separate command to execute. The request body receives limited single-quote escaping, but this does not make the complete command safe because other command components rem ...[truncated 1758 chars]
Remediation
View remediation
[ '-H', `${key}: ${value}`, ]), '-d', JSON.stringify(body), ]; const output = execFileSync('curl', args, { timeout: timeoutMs + 2000, encoding: 'utf8', shell: false, }); ``` 4. Do not pass API keys through command strings. Keep secrets in HTTP header data handled directly by the HTTP client. 5. Validate proxy URLs using `new URL()` and restrict accepted protocols to those explicitly supported. 6. Avoid including complete HTTP responses or authorization headers in error messages. 7. Add tests with malicious proxy and key values to verify that metacharacters cannot trigger shell evaluation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/news-digest.mjs:112
Finding

Feishu Application Secret Exposed in Child Process Command Line

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and operationalizes shell execution, network access, and use of environment-backed secrets, but it does not declare any tool scope such as permissions or allowed-tools. That creates an authorization gap: a broad-trigger skill can cause web requests, CLI execution, and secret-backed actions without explicit least-privilege boundaries or reviewer-visible constraints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file states that the agent summarizes top stories "in Chinese," and later emphasizes "全程中文输出" as a fixed behavior. This appears to force a specific language/locale without documenting user choice, opt-in, or a region-specific justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are very broad and map to common conversational requests like asking for news or updates, making accidental invocation likely. In this skill's context, accidental invocation is more concerning because activation can lead to live web access and outbound Feishu delivery to a target user, potentially causing unintended data retrieval or message sending.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code builds a shell command string and passes it to execSync, incorporating dynamic values such as headers, URL, body, and proxy. Because proxy comes from environment variables and header values include secrets, this creates command-injection risk and expands the skill's capability from simple HTTP requests to arbitrary shell execution if any interpolated value is attacker-controlled.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch-news.mjs (reported line 45)May include surrounding context.

js
const headerArgs = Object.entries(headers).map(([k, v]) => `-H "${k}: ${v}"`).join(' ');
  const proxyArg = proxy ? `--proxy ${proxy}` : '';
  const escaped = JSON.stringify(body).replace(/'/g, "'\\''");
  const cmd = `curl -s --max-time ${Math.floor(timeoutMs / 1000)} ${proxyArg} -X POST "${url}" ${headerArgs} -d '${escaped}'`;
  return JSON.parse(execSync(cmd, { timeout: timeoutMs + 2000 }).toString());
}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt explicitly requires that titles and summaries 'must be in Chinese' and also says non-Chinese sources must be translated into Chinese. This imposes a fixed language policy in the skill's natural-language behavior without offering the user a language choice or documenting an opt-in.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch-news.mjs (reported line 65)May include surrounding context.

js
for (let attempt = 1; attempt <= 2; attempt++) {
    try {
      const data = curlPost(
        'https://api.perplexity.ai/chat/completions',
        { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },
        { model: 'sonar', messages: [{ role: 'user', content: prompt }], max_tokens: 1500 },
        proxy,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The insight-generation path repeats the same unsafe pattern by constructing a curl command with interpolated proxy and API key data and executing it via execSync. This unnecessarily grants shell execution in a feature that only needs outbound HTTPS, so compromise of environment-controlled inputs could lead to arbitrary command execution and secret exposure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch-news.mjs (reported line 122)May include surrounding context.

js
max_tokens: 400,
    }).replace(/'/g, "'\\''");
    const proxyArg = proxy ? `--proxy ${proxy}` : '';
    const cmd = `curl -s --max-time 20 ${proxyArg} -X POST "https://api.ppinfra.com/v3/openai/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer ${ppioKey}" -d '${escaped}'`;
    const data = JSON.parse(execSync(cmd, { timeout: 22000 }).toString());
    return data.choices?.[0]?.message?.content?.trim() || '';
  } catch (e) {

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch-news.mjs (reported line 122)May include surrounding context.

js
max_tokens: 400,
    }).replace(/'/g, "'\\''");
    const proxyArg = proxy ? `--proxy ${proxy}` : '';
    const cmd = `curl -s --max-time 20 ${proxyArg} -X POST "https://api.ppinfra.com/v3/openai/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer ${ppioKey}" -d '${escaped}'`;
    const data = JSON.parse(execSync(cmd, { timeout: 22000 }).toString());
    return data.choices?.[0]?.message?.content?.trim() || '';
  } catch (e) {

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The embedded text and comments describe the skill as producing Chinese content, including 50-60字,中文 and Chinese cover copy, which suggests a language-specific behavior. Under the policy rule, forcing a specific language without opt-in can be a locale-policy violation unless the regional constraint is clearly justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a news briefing workflow, where network retrieval and message delivery are expected. However, this file implements that workflow by spawning subprocesses via execSync and interpolating user-controlled values such as topics, title, and target user into shell command strings, which is a broader and more dangerous capability than the stated purpose requires.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script builds a shell command string with user-controlled values such as topic, date, count/category-derived fields, and optional flags, then executes it with execSync. Quoting is incomplete and brittle for shell metacharacters like embedded double quotes or command substitutions, so an attacker can potentially achieve command injection and run arbitrary commands in the agent environment, with access to environment secrets included in the same execution context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This command passes FEISHU_APP_ID and FEISHU_APP_SECRET into a child process and sends the assembled news digest to a target user, which is a network/data-transmission action. The code logs that it is building a card, but it does not explicitly warn that content will be delivered externally via Feishu using configured credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send-card.mjs (reported line 35)May include surrounding context.

js
}

async function fetchFeishuToken(appId, appSecret) {
  const res = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ app_id: appId, app_secret: appSecret }),

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This code transmits fully attacker-influenced content (title, summary, insight, and url from the input JSON) to an external messaging platform and ultimately to an end user without validation or sanitization. In this skill context, that can enable phishing or social-engineering delivery through trusted Feishu cards, especially because arbitrary URLs are embedded as '查看原文' buttons and rich markdown content is forwarded as-is.

Content

Scanner excerpt · scripts/send-card.mjs (reported line 140)May include surrounding context.

js
}

async function sendCard(token, userId, card) {
  const res = await fetch('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id', {
    method: 'POST',
    headers: { 'Authorization': token, 'Content-Type': 'application/json' },
    body: JSON.stringify({

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code writes a temporary JavaScript file and then invokes node -e through execSync, which are safety-relevant operations for a code file. Although the header comment states the output path, there is no confirmation prompt and no user-facing warning around the temporary file creation or subprocess execution itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The date formatting is hard-coded to zh-CN and Asia/Shanghai, and the surrounding usage/comments are also Chinese-only, with no option for users to choose another locale. This can violate language/locale policy when a skill imposes a specific locale without explicit opt-in or documented regional justification.

Content

No source excerpt is available for this finding.