Back to skill

Security audit

Local Markdown Editor with Live Preview 本地Markdown网页编辑器

Security checks for vulnerabilities and agentic risk

Overview

This is a local Markdown editor, but its local web server exposes broad file access and shutdown controls with weak boundaries.

Review before installing. Only run this on trusted files in a private local environment, avoid binding it beyond localhost, and do not open crafted editor URLs from untrusted sources. The safest remediation would be to add a startup token, remove global CORS, constrain reads and writes to an approved workspace and Markdown-like extensions, safely serialize URL parameters, pin or vendor dependencies, and remove automatic shutdown on page hide/unload.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/app.py:164
Finding

Unrestricted Local File Read and Write Through Unauthenticated API Endpoints

Content
View full analysis
Remediation
View remediation
Path: candidate = (WORKSPACE / user_path).resolve() try: candidate.relative_to(WORKSPACE) except ValueError: raise PermissionError("Path is outside the permitted workspace") return candidate ``` 3. Reject absolute paths unless a file was explicitly selected through a trusted local workflow. 4. Restrict readable and writable extensions to the formats genuinely required by the editor. 5. Prevent symlink escapes by validating resolved targets and, where appropriate, refusing symlinks. 6. Disable global CORS. If cross-origin access is necessary, allow only an explicit trusted origin. 7. Generate an unpredictable session token at startup and require it on every API request. 8. Validate `Origin` and `Host` headers and add CSRF protection to state-changing endpoints. 9. Use atomic writes and avoid automatically creating arbitrary parent directories. 10. Run the server under an account with minimal filesystem privileges. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/app.py:138
Finding

Unsafe JavaScript Construction From the URL File Parameter

Content
View full analysis
Remediation
View remediation
` in the query parameter. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/app.py:309
Finding

Unauthenticated Process-Termination Endpoint and Overbroad Automatic Shutdown

Content
View full analysis
{}); } } ``` ### Technical Analysis `GET /api/shutdown` performs a destructive state change without authentication or authorization. The endpoint uses a method conventionally treated as safe and may therefore be invoked through navigation, prefetching, embedded resources, or cross-origin requests. Once invoked, a background thread calls `os._exit(0)`. This immediately terminates the process without normal Flask shutdown handling, cleanup handlers, buffer flushing, or resource finalization. The frontend compounds the problem by triggering shutdown whenever the document becomes hidden. A visibility transition occurs when switching tabs, minimizing the browser, locking the device, or moving to another application; it does not reliably indicate that the user intends to ...[truncated 1132 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/index.html:7
Finding

Runtime Loading of Unpinned Third-Party Dependencies Without Integrity Protection

Content
View full analysis
``` The installation documentation also specifies unpinned Python dependencies: ```bash pip install flask flask-cors markdown ``` ### Technical Analysis The application executes JavaScript retrieved from third-party CDNs at page-load time. The `marked` URL does not specify an exact version, and none of the CDN resources use Subresource Integrity. Consequently, the effective frontend code can change after the Skill itself has been reviewed. A compromised CDN, compromised package release, account takeover, or incompatible future package update could introduce JavaScript into the editor origin. This origin is unusually sensitive because the local backend exposes filesystem read and write APIs without authorization. A compromised dependency would therefore not be limited to manipulating the page; it could invoke those APIs and access files with the privileges of the Flask process. The Python installation command similarly permits dependency versions to change between installations. No lock file or package hashes are supplied. ### Attack Path 1. The victim opens the local editor while connected to the Internet. 2. The browser requests JavaScript from jsDelivr and cdnjs. 3. A compromised or unexpectedly changed asset is returned. 4. Because no integrity hash is present, the browser accepts and executes the asset. 5. The malicious script runs in the editor origin. 6. It invokes local API endpoints to read files, overwrite files, or terminate the process. 7. Retrieved information can be tr ...[truncated 779 chars]
Remediation
View remediation
``` 4. Apply a Content Security Policy restricting script, style, image, and network destinations. 5. Pin exact Python versions in a requirements or lock file. 6. Use package hashes, such as pip's `--require-hashes`, for reproducible installation. 7. Add automated dependency vulnerability scanning and a controlled update process. 8. Reduce the consequences of dependency compromise by authenticating and restricting all local API endpoints. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Context-Inappropriate Capability

Critical
Category
Not specified by scanner
Confidence
100% confidence
Finding

The page automatically sends shutdown requests during pagehide, visibilitychange, and unload, meaning ordinary user actions like switching tabs, minimizing the browser, or navigating away can trigger server termination. This creates a highly fragile design that can be abused for trivial denial of service and makes the editor itself a shutdown trigger unrelated to document editing.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 368)May include surrounding context.

md
2. Edit `index.html` for frontend changes

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

A markdown editor does not need a server power-off control in its normal UI, and exposing one in the client makes service availability dependent on any user who can load the page. If the backend endpoint is reachable without strong authorization, an attacker or even an accidental click can terminate the supporting service and cause denial of service.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The client implements a direct helper that invokes /api/shutdown, including a sendBeacon fallback intended to make delivery reliable during page close. That reliability increases the chance of successful unwanted shutdowns and suggests the application is intentionally wiring destructive operational control into an end-user document editor.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · SKILL.md (reported line 20)May include surrounding context.

md
- Connect to external servers (except CDN for libraries)
- Send data outside your local machine
- Require internet access for core functionality
- Execute arbitrary code

**Security Features:**
- Localhost-only server (127.0.0.1)

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 271)May include surrounding context.

English:
Open files directly via URL parameter:

text
http://localhost:996/?file=skills/xi-markdown/SKILL.md
  • URL is automatically encoded
  • Supports relative paths from workspace

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 280)May include surrounding context.

English:
Open files directly via URL parameter:

text
http://localhost:996/?file=skills/xi-markdown/SKILL.md
  • URL is automatically encoded
  • Supports relative paths from workspace

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 337)May include surrounding context.

English:
Open files directly via URL parameter:

text
http://localhost:996/?file=skills/xi-markdown/SKILL.md
  • URL is automatically encoded
  • Supports relative paths from workspace

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

The documentation explicitly encourages opening other skills' documentation via relative workspace paths, which normalizes cross-skill file access. In the context of a local Flask service that accepts file paths through URL/API parameters, this broadens the attack surface for workspace enumeration and unauthorized reading of adjacent files.

Content

Scanner excerpt · SKILL.md (reported line 313)May include surrounding context.

Edit a skill's documentation:

bash
python app.py "skills\a-stock-get\SKILL.md"
# or via URL: http://localhost:996/?file=skills/a-stock-get/SKILL.md

Edit Ace Banana2 skill:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The save endpoint accepts unauthenticated file paths and content, then writes directly to disk, including resolution of relative paths into the workspace. Any reachable client can modify arbitrary files accessible to the process, which can lead to data loss, tampering, or code/configuration overwrite.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The application exposes an unauthenticated HTTP shutdown endpoint that any party able to reach the Flask server can invoke. Because the server also enables CORS globally and does not enforce local-only trust at the endpoint, this creates a trivial denial-of-service condition unrelated to normal markdown editing behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The shutdown endpoint performs destructive termination immediately and without any warning, confirmation, or authorization checks. In the context of a local editor service, this unnecessarily exposes a denial-of-service primitive to any party with network access to the server.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The force-restart logic sends an HTTP request to whatever host and port are supplied in order to trigger /api/shutdown. While intended for local instance management, it can target arbitrary destinations when host is user-controlled, causing unintended requests and potentially shutting down another compatible service on that endpoint.

Content

No source excerpt is available for this finding.

Dynamic Request Target

Medium
Category
Server-Side Request Forgery
Confidence
76% confidence
Finding

The request target is dynamically built from host and port arguments and fetched with requests.get. In this tool the behavior is meant for local restart handling, so it is not classic attacker-driven SSRF via a remote request, but it still permits arbitrary outbound requests to user-specified destinations and can interact with internal services unexpectedly.

Content

Scanner excerpt · scripts/app.py (reported line 377)May include surrounding context.

python
try:
        import requests
        try:
            requests.get(f'http://{host}:{port}/api/shutdown', timeout=1)
        except:
            pass
    except:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document sets the page language to zh-CN and the visible interface strings throughout the file are in Simplified Chinese, with no option for users to select another language. This creates a language/locale policy issue because the skill imposes a specific locale without opt-in or an explicit region-specific justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Sending automatic shutdown requests without warning or confirmation violates safe UX for destructive operations and amplifies the denial-of-service risk from normal browsing behavior. Even if the shutdown endpoint were intended for admins, silent triggering on page lifecycle events is unsafe because users are not informed that leaving or hiding the page can terminate the service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.