Back to skill

Security audit

flomo-archive

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it fetches personal Flomo notes and saves them to an insecure predictable /tmp file while using a shell-built command to call the local MCP tool.

Install only if you are comfortable letting the skill use your local mcporter Flomo configuration to retrieve monthly personal notes. Review or modify it before use so exports go to a private user-controlled directory with restrictive permissions, and avoid running it in shared or privileged environments until shell=True and the predictable /tmp write are fixed.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_month.py:174
Finding

Predictable Temporary File Permits Symlink-Based Overwrite and Local Data Exposure

Content
View full analysis

Vulnerability Details

File Location: scripts/fetch_month.py, lines 174–176
Vulnerability Type: Predictable and insecure temporary-file handling
Risk Level: Medium

python
output_file = f"/tmp/flomo_{args.year}_{args.month:02d}.json"
with open(output_file, 'w', encoding='utf-8') as f:
    json.dump(result['memos'], f, ensure_ascii=False, indent=2)

Technical Analysis

The script stores complete Flomo note contents at a predictable path in the shared /tmp directory. Python's ordinary open(..., 'w') follows symbolic links and truncates an existing target. It does not provide exclusive creation, symbolic-link rejection, or an explicit restrictive permission mode.

Because the year and month determine the filename, another local user can predict it before execution and create a symbolic link at that path. When the victim runs the script, the process follows the link and writes using the victim's permissions.

The resulting archive permissions also depend on the process umask. Under a permissive configuration, private note contents may become readable by other local users.

Attack Path

  1. An attacker with local access predicts the output path, such as /tmp/flomo_2025_07.json.
  2. Before the victim runs the skill, the attacker creates that path as a symbolic link to a file writable by the victim.
  3. The victim invokes fetch_month.py for the corresponding year and month.
  4. The script opens the predictable path with truncation enabled and follows the symbolic link.
  5. The linked target is truncated and replaced with serialized Flomo note data.
  6. If resulting permissions are insufficiently restrictive, the attacker may also read the archived private notes.

The attacker cannot use this issue to overwrite files the victim process lacks permission to modify.

Impact Assessment

Successful exploitation can compromise:

  • Integrity and availability: Arbitrary files writable by the victim may be truncated and replaced.
  • **C ...[truncated 406 chars]
Remediation
View remediation

Remediation Suggestions

  • Store archives in a user-private directory rather than shared /tmp, with the directory mode restricted to 0700.
  • Create output files atomically and exclusively with mode 0600.
  • Reject symbolic links by using os.open() with O_CREAT | O_EXCL | O_WRONLY and O_NOFOLLOW where supported.
  • Alternatively, use Python's tempfile facilities to generate an unpredictable, securely created file.
  • If the final filename must remain stable, securely create a temporary file in the same private directory, flush and close it, and then atomically rename it.
  • Refuse to overwrite an existing output path unless the user explicitly requests replacement and the path has been validated as a regular file owned by the current user.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The Chinese description overstates capabilities by claiming automatic quality marking and a three-level fallback strategy, while the visible behavior only reflects a two-level week→day approach and includes plaintext persistence to /tmp without prominently declaring that as a data-handling behavior. Misrepresenting functionality around data processing and storage is risky because it can cause users to expose sensitive note content under false expectations about automation, completeness, and retention.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The Chinese description overstates capabilities by claiming automatic quality marking and a three-level fallback strategy, while the visible behavior only reflects a two-level week→day approach and includes plaintext persistence to /tmp without prominently declaring that as a data-handling behavior. Misrepresenting functionality around data processing and storage is risky because it can cause users to expose sensitive note content under false expectations about automation, completeness, and retention.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

This is a true tool-parameter abuse risk because untrusted parameters are embedded into a shell command used to invoke mcporter. Even though current callers mostly provide date strings, the helper is generic and could be reused with attacker-controlled values, enabling command injection or unintended tool invocations under the user's authority.

Content

Scanner excerpt · scripts/fetch_month.py (reported line 26)May include surrounding context.

python
cmd_parts.append(f'{k}="{v}"')
    cmd = " ".join(cmd_parts)
    
    result = subprocess.run(
        cmd, 
        capture_output=True, 
        text=True,

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/fetch_month.py (reported line 31)May include surrounding context.

python
capture_output=True, 
        text=True, 
        shell=True,
        env=os.environ.copy()
    )
    try:
        return json.loads(result.stdout)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises operational behaviors that imply shell, file read/write, and environment access, but it declares no explicit tool scope or permission boundaries. In an agent environment, this increases the chance of over-broad tool use, unexpected local file access, or unintended execution paths beyond what the user reasonably expects.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Overly broad trigger phrases can cause the skill to activate in contexts where the user did not intend note export or analysis, especially for vague requests like pulling history or evaluating notes. In this skill's context, unintended activation is more dangerous because the workflow may fetch, analyze, and locally store personal notes, creating privacy and data-minimization risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill writes complete note data to /tmp but does not clearly warn users in the main description that their personal content will be saved locally. This is particularly dangerous because /tmp is commonly shared, ephemeral, or accessible by other local processes/users depending on system configuration, creating a direct confidentiality risk for potentially sensitive notes.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The script builds a shell command by concatenating tool arguments into a single string and executes it with shell=True. Because year/month-derived date values and other kwargs ultimately flow into that command without safe argument separation, a crafted value containing shell metacharacters could trigger command injection and arbitrary command execution in the user's environment.

Content

Scanner excerpt · scripts/fetch_month.py (reported line 26)May include surrounding context.

python
cmd_parts.append(f'{k}="{v}"')
    cmd = " ".join(cmd_parts)
    
    result = subprocess.run(
        cmd, 
        capture_output=True, 
        text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The subprocess invocation launches a shell-backed external tool without clear user disclosure, increasing risk because the action is both privileged and opaque. In this skill context, the danger is amplified by the fact that the command is assembled dynamically and inherits the user's environment, so the user may unknowingly trigger external execution with their local credentials and tokens.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest claims the skill can evaluate memo quality and automatically mark low-quality notes. In this file, analyze_memos only counts tags, word counts, and activity distribution; it does not score quality or flag specific low-quality memos, so the implemented behavior falls short of the stated capability.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill silently persists fetched Flomo memo contents to /tmp even though its main stated purpose is retrieval and evaluation. This creates an unnecessary local data exposure risk because note contents may contain sensitive personal information and temporary directories are often accessible to other local processes or retained longer than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script writes full memo contents to /tmp by default in non-JSON mode without user warning or consent. Because Flomo notes are likely personal and sensitive, silent persistence materially increases confidentiality risk in a note-archiving skill where users may expect retrieval and summary, not local archival side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description defines invocation examples only in Chinese and does not indicate that other languages are supported or that Chinese is a required locale for a region-specific tool. This can constitute a language policy issue because the skill appears to impose a specific language without user opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language documentation, comments, and CLI usage/output entirely in Chinese, which effectively forces a specific language for users running or maintaining the skill. The policy allows locale constraints only when explicitly documented and justified, or when users are given a choice; neither appears here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script's user-facing description, help text, status messages, and output labels are written only in Chinese, which imposes a specific language/locale without any documented opt-in or alternative. This matches the policy-violation category for language or locale constraints lacking user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script accesses a user-scoped configuration file under ~/.openclaw/workspace/config/mcporter.json, which may contain connection details or credentials, but this access is only described in an internal docstring/comment and not disclosed to the user during execution. Under the code-file warning rule, sensitive configuration or credential access should have some visible user disclosure unless clearly covered elsewhere.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.