Back to skill

Security audit

Content Clipper

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its clipping purpose, but it defaults to sending clipped content to a published Flomo webhook and uses an unsafe Windows shell command, so it should be reviewed before use.

Install only after reviewing the data flow. Configure your own FLOMO_WEBHOOK before any Flomo use, avoid clipping private or authenticated pages, prefer markdown for sensitive content, and do not use the Windows Flomo path until the shell-based curl command and proxy bypass are removed.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/clip.js:88
Finding
Windows Shell Command Injection Through Untrusted Clipped Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clip.js`, lines 88-97 **Vulnerability Type**: OS command injection **Risk Level**: High ```js function postToFlomo(content, tags) { const tagStr = tags.map(t => `#${t}`).join(' '); const body = JSON.stringify({ content: tagStr ? `${tagStr}\n\n${content}` : content }); try { const result = execSync( `curl.exe --noproxy "*" -s -X POST "${FLOMO_WEBHOOK}" -H "Content-Type: application/json" -d ${JSON.stringify(body).replace(/"/g, '\\"')}`, { encoding: 'utf8', timeout: 15000 } ); ``` ### Technical Analysis The function builds an operating-system command by directly interpolating the Flomo webhook URL and a JSON body containing clipped content and user-supplied tags. The resulting string is passed to `execSync`, which executes it through a shell. Replacing double quotes with `\"` does not safely escape data for Windows `cmd.exe`. Shell metacharacters such as `&`, `|`, `>`, `<`, `^`, and environment-variable expansion through `%...%` may retain special meaning depending on the final quoting context. The content originates from a remote webpage, while tags and `FLOMO_WEBHOOK` can also be supplied externally. Consequently, attacker-controlled input crosses directly from an untrusted source into a shell command. The later HTTPS fallback does not mitigate the issue because it is only reached after the initial command has already been executed or has failed. ### Attack Path 1. An attacker creates or compromises a webpage containing text with Windows shell metacharacters and a command payload. 2. The attacker persuades a user or Agent to clip that URL using the default Flomo target. 3. `fetch()` downloads the page and `extractText()` places the attacker-controlled text in `content`. 4. `main()` includes that text in `clipContent` and passes it to `postToFlomo()`. 5. `postToFlomo()` serializes the content into `body` and interpolates it into the `curl.exe` command string. 6. `ex ...[truncated 675 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `execSync` delivery path and use Node.js `https.request()` or the built-in `fetch()` API for every platform. - Do not invoke a command shell to transmit HTTP data. - If an external executable is strictly required, use `execFile()` or `spawn()` with: - A fixed executable path. - An argument array rather than a concatenated command string. - `shell: false`. - Strict validation of the webhook URL. - Restrict webhook destinations to HTTPS and, where appropriate, an allowlist of expected hosts. - Treat downloaded webpage content, tags, and environment variables as untrusted data. - Add regression tests containing Windows shell metacharacters to verify that they are transmitted only as data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/clip.js:9
Finding
Hardcoded Third-Party Flomo Webhook Causes Credential Exposure and Unintended Data Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clip.js`, line 9 and lines 130-137; `SKILL.md`, lines 24-26 **Vulnerability Type**: Hardcoded secret and unsafe external-data transmission default **Risk Level**: Medium ```js const FLOMO_WEBHOOK = process.env.FLOMO_WEBHOOK || 'https://flomoapp.com/iwh/MTg4MTA/c6fceb66258d3cc5c527d82f283ba06a/'; ``` ```js if (opts.target === 'flomo') { console.error('Posting to flomo...'); const result = await postToFlomo(clipContent, opts.tags); console.log(JSON.stringify({ ok: true, target: 'flomo', title, contentLength: content.length, result })); } else if (opts.target === 'markdown') { const outPath = opts.output || `clip_${Date.now()}.md`; saveMarkdown(title, content, opts.url, opts.tags, outPath); ``` The documentation also publishes the credential: ```md ## Flomo Configuration Set webhook URL in the script or via environment variable `FLOMO_WEBHOOK`. Default webhook (Candy): https://flomoapp.com/iwh/MTg4MTA/c6fceb66258d3cc5c527d82f283ba06a/ ``` ### Technical Analysis The source code and documentation embed a Flomo incoming-webhook URL. Such URLs function as bearer credentials: possession of the URL is generally sufficient to submit content to the associated account. The argument parser also selects `flomo` as the default target. If a user does not define `FLOMO_WEBHOOK` and does not explicitly choose Markdown output, the Skill sends extracted content to the published webhook. This may include sensitive material from internal, private, or authenticated pages. The behavior is documented rather than concealed, but publishing a reusable webhook credential and using an account-specific external destination by default violates secure secret management and safe-default principles. ### Attack Path 1. A user installs or invokes the Skill without setting `FLOMO_WEBHOOK`. 2. The user supplies a URL and does not override the default output target. 3. The Skill downloads and extracts the page content. ...[truncated 930 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Immediately revoke and rotate the published Flomo webhook. - Remove the webhook from both source code and documentation. - Require users to provide their own webhook through a protected configuration mechanism or environment variable. - Fail closed with a clear error when the webhook is absent rather than falling back to a shared credential. - Make local Markdown output the default target. - Require explicit confirmation before transmitting clipped content to an external service. - Clearly display the destination hostname and describe what data will be sent. - Avoid logging or returning webhook secrets. - Add secret scanning to the development and release process to prevent credentials from being committed again. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/clip.js:94
Finding
Global Proxy Bypass for Flomo Webhook Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clip.js`, line 94; `SKILL.md`, line 29 **Vulnerability Type**: Network policy and egress-control bypass **Risk Level**: Low ```js const result = execSync( `curl.exe --noproxy "*" -s -X POST "${FLOMO_WEBHOOK}" -H "Content-Type: application/json" -d ${JSON.stringify(body).replace(/"/g, '\\"')}`, { encoding: 'utf8', timeout: 15000 } ); ``` The corresponding documentation states: ```md - Windows: uses `curl.exe --noproxy '*'` for flomo webhook (proxy bypass needed) ``` ### Technical Analysis The `--noproxy "*"` option instructs curl to bypass configured proxies for every destination. This forces direct network communication even where a user or organization has configured a proxy for access control, monitoring, filtering, or audit logging. A global proxy bypass is broader than necessary for the clipping function and weakens environmental security controls. It also creates inconsistent behavior: the initial Windows curl request bypasses the proxy, while the Node.js fallback may follow different network configuration. ### Attack Path 1. A Windows environment configures an outbound proxy for monitoring or enforcing network policy. 2. A user invokes the Skill with the Flomo target. 3. The Skill launches curl with `--noproxy "*"`. 4. Curl attempts to connect directly to the webhook destination rather than using the configured proxy. 5. If direct outbound connectivity is permitted, clipped content leaves the host without passing through the expected proxy controls. ### Impact Assessment The bypass may prevent expected inspection, logging, filtering, or destination restrictions from applying to submitted content. It does not itself grant local administrative privileges, and successful bypass depends on direct outbound network connectivity. Its primary scope is circumvention of network-level least-privilege and monitoring controls for the webhook request. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `--noproxy "*"` and respect the host's configured network policy. - Use Node.js HTTPS APIs consistently instead of platform-specific curl commands. - If proxy bypass is genuinely required in a specific deployment, make it an explicit opt-in configuration rather than a default. - Scope any exception to a validated hostname instead of using the wildcard `*`. - Display a warning before bypassing proxy controls and document the security implications. - Coordinate required proxy exceptions with the system or network administrator rather than bypassing controls in application code. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Missing User Warnings

High
Confidence
98% confidence
Finding
The script hard-codes a default FLOMO_WEBHOOK, so clipped content is sent to a remote endpoint even when the user does not provide their own webhook. That creates a real data exfiltration risk: any fetched page content, potentially including sensitive internal URLs or private text, is transmitted to an embedded third-party destination without clear consent.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger phrases are broad and map to common requests like summarizing URLs, saving notes, or clipping content, which increases the chance the skill activates in situations where users do not expect external transmission or file writes. In this skill's context, that broad scope is riskier because the actions include sending data to a webhook and writing local files.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill description does not clearly warn that clipped content may be transmitted to an external webhook service. Because the skill processes arbitrary shared URLs and extracted content, users may unknowingly disclose sensitive material, private links, or copyrighted text to an external endpoint.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The documentation includes a concrete flomo webhook URL tied to a specific destination rather than a generic placeholder. This can cause user-clipped content to be sent to an unintended third-party account, exposing private notes, URLs, summaries, or extracted content without meaningful user awareness or consent.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The file-level documentation describes a web content clipper that extracts content and sends it to flomo or markdown. Spawning a shell command through child_process.execSync is not an obvious requirement for that purpose, because the same operation can be performed directly with Node's HTTP libraries and the code already includes such a fallback.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The saveMarkdown function writes clipped content directly to disk with fs.writeFileSync, which affects local user data. Although this is part of the markdown target behavior, the code provides no explicit user-facing warning or comment near the write operation that local files will be created or overwritten at the specified path.

Natural-Language Policy Violations

Low
Confidence
66% confidence
Finding
The invocation guidance mixes English and Chinese trigger phrases and references Chinese platforms, but it does not clearly state whether language use is optional or user-selected. This may create an implicit locale preference without documenting user choice or a justified region-specific limitation.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The markdown output mode writes clipped content to a local file, but the description does not warn users that running the command will create or overwrite local files at the specified path. While less severe than external exfiltration, this can still cause accidental data placement in sensitive directories or unintended persistence of extracted content.

Intent-Code Divergence

Low
Confidence
83% confidence
Finding
The inline comment frames the Node https path as a fallback, which implies the surrounding behavior is a normal in-process HTTP implementation. In reality, the primary path is external command execution via curl.exe, so the comment obscures the true operational behavior of the function.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/clip.js:87

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/clip.js:11