Back to skill

Security audit

WeRead to flomo

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims: it syncs user-selected WeRead Markdown notes to a flomo webhook, with local deduplication state and no hidden persistence or unrelated behavior.

Install only if you are comfortable sending selected WeRead highlights and notes to flomo. Use --dry-run first, prefer today or date before all, keep the webhook private, verify the webhook URL is your own HTTPS flomo endpoint, and consider rotating the webhook if it has appeared in shell history, logs, or process captures.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/weread_to_flomo.py:112
Finding

Unrestricted Webhook Destination Enables Sensitive Note Disclosure and SSRF

Content
View full analysis
dict: data = urllib.parse.urlencode({'content': content}).encode() req = urllib.request.Request(webhook, data=data, method='POST') with urllib.request.urlopen(req, timeout=20) as resp: return json.loads(resp.read().decode('utf-8', 'ignore')) ``` The destination is accepted directly from a command-line argument: ```python parser.add_argument('--flomo-webhook', required=True) ``` The exported note content is then sent to that destination: ```python result = post_to_flomo(args.flomo_webhook, content) ``` ### Technical Analysis The script treats any value supplied through `--flomo-webhook` as a trusted flomo endpoint. It does not validate: - Whether the URL uses HTTPS. - Whether the hostname belongs to an official flomo service. - Whether the destination resolves to a loopback, link-local, or private address. - Whether an HTTP redirect changes the request destination to an untrusted host. Consequently, the function can transmit private WeRead note content to an attacker-controlled endpoint over HTTP or HTTPS. It can also be used to issue POST requests to services accessible from the machine running the skill, including local or internal-network services. Because the body is URL-encoded and controlled by parsed note content, this does not by itself provide arbitrary code execution. However, it provides an outbound data-disclosure channel and limited server-side request forgery capabilities using the network privileges of the executing host. ### Attack Path 1. An attacker, unsafe wrapper, or misleading instruction provides a URL through `--flomo-webhook`. 2. The user runs the script, potentially with `--mode all`. 3. The script parses all matching Markdown files in the s ...[truncated 1024 chars]
Remediation
View remediation
str: parsed = urlsplit(webhook) if parsed.scheme != "https": raise ValueError("The flomo webhook must use HTTPS") if parsed.hostname not in ALLOWED_WEBHOOK_HOSTS: raise ValueError("Unapproved flomo webhook host") return webhook ``` DNS resolution and redirect validation should be added in addition to this basic hostname check. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/weread_to_flomo.py:133
Finding

Webhook Credential Exposed Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs operations that read local Markdown exports, write a local state file, and send data to a remote flomo webhook, but it does not declare any explicit tool scope or permissions boundary. This creates a mismatch between documented behavior and declared capabilities, making it easier for an agent or user to run file and network actions without clear review of what resources may be accessed or exfiltrated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example format requires the tag #02_读书 #02_读书/「<book title>」, which imposes a specific language/locale convention in the skill output. The file does not indicate that this is optional, user-configurable, or limited to a justified region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script forces all time handling into the Asia/Shanghai timezone via a hard-coded constant, which is a locale-specific behavior applied to all users. There is no opt-in, configuration option, or documentation in this file justifying why this locale restriction is required.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script transmits user reading highlights and notes to an arbitrary webhook endpoint without any explicit confirmation, destination validation, or warning about the sensitivity of the content. In this skill’s context, the data being sent can include private annotations and reading history, so accidental misconfiguration or use of an untrusted webhook could result in unintended disclosure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.