Back to skill

Security audit

Supernote Cloud

Security checks for vulnerabilities and agentic risk

Overview

This Supernote skill mostly does what it says, but it handles credentials, uploads, and web fetching with weak safeguards that warrant manual review before use.

Install only after reviewing the security tradeoffs. Use a trusted HTTPS Supernote endpoint, avoid running the script with elevated privileges, do not upload sensitive files or private URLs until the token cache and Python interpolation issues are fixed, and treat article fetching as network access from your agent host.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/supernote.sh:44
Finding

Arbitrary Python Code Execution Through Unsafe Shell Interpolation

Content
View full analysis
time.time() + 3600: sys.exit(0) else: sys.exit(1) except: sys.exit(1) " 2>/dev/null } ``` ```bash HASHED_PASS=$(python3 -c " import hashlib md5 = hashlib.md5('$SUPERNOTE_PASSWORD'.encode()).hexdigest() print(hashlib.sha256((md5 + '$RANDOM_CODE').encode()).hexdigest()) ") ``` ```bash FOUND_ID=$(echo "$RESP" | python3 -c " import sys, json data = json.load(sys.stdin) target = '$PART' for item in data.get('userFileVOList', data.get('data', {}).get('userFileVOList', [])): if item.get('fileName') == target and item.get('isFolder') == 'Y': print(item['id']) break " 2>/dev/null) ``` ```bash FILE_MD5=$(python3 -c "import hashlib; print(hashlib.md5(open('$FILE_PATH','rb').read()).hexdigest())") ``` ### Technical Analysis The script inserts shell variables directly into Python source passed to `python3 -c`. Shell quoting does not make these values safe inside a Python string literal. A single quote, backslash, newline, or other Python syntax in one of the interpolated values can terminate the intended string and alter the executed program. Affected values include: - `$PART`, derived from the user-controlled `--path` argument. - `$FILE_PATH`, derived from the user-controlled `--file` argument. - `$SUPERNOTE_PASSWORD`, supplied through the environment. - `$TOKEN`, read from a predictable local token file or returne ...[truncated 1659 chars]
Remediation
View remediation
time.time() + 3600 else 1) except Exception: raise SystemExit(1) ' "$TOKEN" ``` Apply the same pattern to every affected value: - Pass `$SUPERNOTE_PASSWORD` and `$RANDOM_CODE` as separate `sys.argv` entries. - Pass `$PART` as an argument while keeping the API response on standard input. - Pass `$FILE_PATH` as an argument rather than placing it inside `open('...')`. - Prefer a dedicated Python helper file over several dynamically constructed `python3 -c` programs. - Add regression tests using values containing quotes, backslashes, newlines, Unicode, and shell/Python metacharacters. - Avoid executing the Skill with administrative privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/supernote.sh:28
Finding

Predictable Shared Token Cache Enables Symlink Attacks and Authentication-State Confusion

Content
View full analysis
"$TOKEN_FILE" chmod 600 "$TOKEN_FILE" ``` ### Technical Analysis The bearer token is stored at a fixed, globally predictable path under `/tmp`. The script does not verify ownership, reject symbolic links, or create the file atomically. The redirection in `echo "$TOKEN" > "$TOKEN_FILE"` opens the path before `chmod 600` is applied. Consequently: - A pre-existing symbolic link can cause the write to follow an attacker-selected path. - There is a race window between opening the file and changing its permissions. - Different Supernote accounts or server configurations run by the same operating-system user share one cache. - Concurrent invocations can read or overwrite partial or unrelated authentication state. - A manipulated token can reach the unsafe Python interpolation in `is_token_valid`, increasing the severity when combined with the code-injection finding. The practical effect of a symlink depends on the permissions of the process. A non-privileged process cannot overwrite files it otherwise lacks permission to modify, but privileged execution substantially increases the impact. ### Attack Path 1. A local attacker predicts the fixed path `/tmp/.supernote_token`. 2. The attacker pre-creates that path, races its creation, or substitutes a symbolic link where local permissions permit. 3. The Skill logs in and writes the bearer token through shell redirection. 4. The token may be written to an uninte ...[truncated 912 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/supernote.sh:62
Finding

Authentication Material and Bearer Tokens Can Be Transmitted Over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/article2ebook.py:27
Finding

Unrestricted Article and Image Fetching Enables Server-Side Request Forgery

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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a multi-function Supernote cloud integration skill centered on accessing and managing files on a self-hosted Supernote Private Cloud, with article conversion as one feature among several. The supplied code chunk only implements the article conversion portion: it retrieves a URL over HTTP, extracts readable article content, optionally downloads images, and writes an EPUB or PDF/HTML file locally. There is no code for connecting to a Supernote cloud service, listing remote files, navigating folders, uploading content, sending output to a device, or checking storage usage. Because the actual code covers only a narrow subset of the declared purpose and lacks the primary cloud-management capabilities, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/supernote.sh (reported line 68)May include surrounding context.

sh
do_login() {
  # Step 1: Get random code
  local RANDOM_RESP
  RANDOM_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "withCredentials: true" \
    "$BASE_URL/api/official/user/query/random/code" \

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/supernote.sh (reported line 88)May include surrounding context.

sh
# Step 3: Login
  local LOGIN_RESP
  LOGIN_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "withCredentials: true" \
    "$BASE_URL/api/official/user/account/login/new" \

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/supernote.sh (reported line 314)May include surrounding context.

sh
# Step 1: Apply for upload
  local APPLY_RESP
  APPLY_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "x-access-token: $TOKEN" \
    -H "withCredentials: true" \

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/supernote.sh (reported line 334)May include surrounding context.

sh
# Step 2: Upload to OSS
  local OSS_RESP
  OSS_RESP=$(curl -s -X POST \
    -H "x-access-token: $TOKEN" \
    -F "file=@$FILE_PATH" \
    "$UPLOAD_URL")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises and demonstrates shell, network, and file-writing behavior but does not declare any explicit tool scope or permissions boundaries. This is dangerous because it increases the chance that an agent runtime will execute higher-risk operations without clear operator review, violating least-privilege expectations and making unintended network access or file modification easier.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill encourages fetching arbitrary URLs and uploading content to a self-hosted cloud/device but does not clearly warn users that remote websites will be contacted and local or generated content may be transmitted to another system. This can expose sensitive URLs, metadata, credentials-adjacent information, or private documents, especially in an agent context where users may not realize a network action is occurring.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sets the book language to 'en' and also marks chapter content as lang='en' regardless of the source article language. This forces a specific locale in output metadata without any user opt-in or indication that the tool is limited to English content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest frames this skill around Supernote cloud file access and article-to-ebook conversion, but this script's PDF fallback achieves conversion by spawning local system tools and even launching a separate Python process. Executing host binaries is not justified by the declared Supernote integration purpose and materially expands capability beyond straightforward network retrieval and document generation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/article2ebook.py (reported line 234)May include surrounding context.

python
# Try using /usr/sbin/cupsfilter (macOS built-in)
    try:
        result = subprocess.run(
            ['/usr/bin/python3', '-c', f'''
import subprocess, sys
# Use macOS Automator/AppKit for HTML to PDF

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/article2ebook.py (reported line 253)May include surrounding context.

python
# Actually, let's just save as HTML and note it in output
    try:
        # cupsfilter can convert HTML to PDF on macOS
        result = subprocess.run(
            ['cupsfilter', tmp_html],
            capture_output=True, timeout=30
        )

Tainted flow: 'output_path' from requests.get (line 303, network input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/article2ebook.py (reported line 258)May include surrounding context.

python
capture_output=True, timeout=30
        )
        if result.returncode == 0 and result.stdout:
            with open(output_path, 'wb') as f:
                f.write(result.stdout)
            os.unlink(tmp_html)
            return output_path

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/supernote.sh (reported line 68)May include surrounding context.

sh
do_login() {
  # Step 1: Get random code
  local RANDOM_RESP
  RANDOM_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "withCredentials: true" \
    "$BASE_URL/api/official/user/query/random/code" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script transmits the account identifier and a password-derived login value to remote endpoints via curl, but there is no confirmation prompt or explicit user-facing warning at the point of transmission. Although the header comments list required environment variables, they do not warn that credentials will be sent over the network, including to example non-HTTPS endpoints.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The script sends credential-derived authentication material to whatever URL is placed in SUPERNOTE_URL, including plain HTTP as shown in the example. In the skill context, users are expected to connect to a self-hosted service, which increases the chance of misconfiguration or use on untrusted networks; without enforcing HTTPS or validating the host, credentials and session tokens can be exposed to interception or malicious endpoints.

Content

Scanner excerpt · scripts/supernote.sh (reported line 88)May include surrounding context.

sh
# Step 3: Login
  local LOGIN_RESP
  LOGIN_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "withCredentials: true" \
    "$BASE_URL/api/official/user/account/login/new" \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/supernote.sh (reported line 103)May include surrounding context.

sh
fi

  echo "$TOKEN" > "$TOKEN_FILE"
  chmod 600 "$TOKEN_FILE"
}

api_post() {

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

All authenticated API calls reuse the bearer token and transmit it to the configured BASE_URL without any transport-security enforcement. In this skill, browsing file listings and storage info seems routine, so operators may not realize a misconfigured or MITM-controlled server can harvest the token and access cloud contents.

Content

Scanner excerpt · scripts/supernote.sh (reported line 111)May include surrounding context.

sh
local DATA="$2"
  local TOKEN
  TOKEN=$(get_token)
  curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "x-access-token: $TOKEN" \
    -H "withCredentials: true" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The upload-apply request sends file metadata and authentication to the configured remote server, again without ensuring a secure transport or trusted destination. Because this command precedes file transfer, a malicious or spoofed endpoint can collect sensitive file names, sizes, hashes, and session tokens before the user notices.

Content

Scanner excerpt · scripts/supernote.sh (reported line 314)May include surrounding context.

sh
# Step 1: Apply for upload
  local APPLY_RESP
  APPLY_RESP=$(curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "x-access-token: $TOKEN" \
    -H "withCredentials: true" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The upload path performs multiple HTTP requests culminating in transmission of the local file via curl, but the function does not provide any warning or confirmation before sending the file contents to the server. The success message appears only after the upload, so users are not explicitly warned at execution time about this data transfer.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The script uploads the file body to UPLOAD_URL returned by the server and does not validate that this URL is trustworthy, uses HTTPS, or belongs to the expected storage domain. A malicious or compromised Supernote server can redirect uploads to an attacker-controlled endpoint, causing direct exfiltration of arbitrary local files selected for upload.

Content

Scanner excerpt · scripts/supernote.sh (reported line 334)May include surrounding context.

sh
# Step 2: Upload to OSS
  local OSS_RESP
  OSS_RESP=$(curl -s -X POST \
    -H "x-access-token: $TOKEN" \
    -F "file=@$FILE_PATH" \
    "$UPLOAD_URL")

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The header usage block documents login, listing, tree navigation, directory lookup, upload, and capacity commands, but it does not mention the later-implemented send-article/article command. This is not merely incomplete help text in isolation: the documented command surface materially understates that the script can fetch and convert arbitrary URLs into ebooks and upload them.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The login payload sets "language":"en" unconditionally, which forces a specific locale in natural-language behavior without offering user opt-in or documenting why English is required. This matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.