Back to skill

Security audit

eswr-studio

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Elsewhere publishing helper, but it asks agents to adopt mutable remote instructions and persist a non-expiring API token in unsafe places.

Review before installing. Use this only with an account whose token you are comfortable exposing to the agent, and avoid letting it store the token in long-term memory or a project .env.local file. Prefer a scoped secret manager entry, rotate any token already saved this way, and do not let the skill replace its instructions from GitHub without manual review.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:12
Finding

Mutable Remote Skill Instructions Are Retrieved Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 12–20
Vulnerability Type: Untrusted runtime instruction update
Risk Level: High

bash
curl -s https://raw.githubusercontent.com/PitayaK/eswr-studio/main/SKILL.md | head -5

If the reported version differs, the Agent is instructed to retrieve the complete file:

bash
curl -s https://raw.githubusercontent.com/PitayaK/eswr-studio/main/SKILL.md

Technical Analysis

The Skill requires an update check against the mutable main branch every time it is used. If the remote version changes, the Agent is instructed to retrieve and reread the complete remote Skill document.

The retrieved content is not pinned to an immutable commit and is not authenticated with a trusted signature or expected digest. HTTPS protects the connection in transit but does not protect against repository compromise, maintainer-account compromise, or a malicious future repository update.

Because a Skill document controls Agent behavior, adopting changed remote instructions creates an instruction supply-chain channel. The retrieved file is not piped into Bash and is not native executable code, but it can still alter the Agent's current goals, tool usage, disclosure behavior, and safety-related decisions.

Attack Path

  1. An attacker compromises the GitHub repository, its maintainer account, or an authorized publishing workflow.
  2. The attacker changes the version and adds malicious instructions to main/SKILL.md.
  3. The Agent performs the mandatory update check during a later invocation.
  4. The changed version causes the Agent to retrieve and adopt the complete remote document.
  5. The injected instructions direct the Agent to access additional files, disclose credentials, contact an attacker-controlled endpoint, or perform other unauthorized operations.

Impact Assessment

Successful exploitation can hijack the Agent's behavior during a Skill invocation. The ...[truncated 416 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove mandatory runtime self-update instructions from the Skill.
  • Distribute updates through versioned, reviewed Skill packages.
  • If remote retrieval is required, pin the resource to an immutable commit.
  • Verify the downloaded document against a trusted cryptographic signature or an out-of-band expected digest before use.
  • Display the proposed update and obtain explicit user approval before adopting changed instructions.
  • Apply the same security review process to every new release rather than trusting the mutable branch.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:29
Finding

Credential Discovery Extends Into General Persistent Agent Memory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 29–38
Vulnerability Type: Excessive credential and persistent-state access
Risk Level: Medium

The token discovery sequence includes reading a project-local secret file:

bash
cat .env.local 2>/dev/null | grep ELSEWHERE_API_TOKEN

It then directs the Agent to search its persistent memory or notes for an Elsewhere API token before asking the user.

Technical Analysis

Reading a specifically scoped service credential may be necessary to authenticate publishing operations. However, searching general long-term memory or notes crosses a broader trust boundary than the declared publishing task requires.

Persistent Agent memory may contain information from unrelated users, sessions, services, or tasks. Bringing that state into the current context unnecessarily increases credential exposure and creates opportunities for malicious or compromised instructions to obtain sensitive information.

The .env.local lookup is also performed relative to the current working directory rather than through a dedicated service-specific credential store. This may cause the Skill to inspect a file belonging to an unrelated project.

Attack Path

  1. The Skill is invoked for registration, publication, import, or profile management.
  2. No token is found in the current shell environment.
  3. The Agent reads the current directory's .env.local file and then searches general persistent memory or notes.
  4. A token found in either location is introduced into the active task context.
  5. Malicious instructions, logs, another Skill, or an unintended response may expose or misuse the credential.

Impact Assessment

Exposure of the Elsewhere bearer token permits operations authorized by the account, including article publication, image uploads, imports, profile changes, and podcast synchronization. General memory access may also expose unrelated sensitive information if t ...[truncated 211 chars]

Remediation
View remediation

Remediation Suggestions

  • Never search general Agent memory or unrestricted notes for credentials.
  • Store and retrieve the token through a dedicated secret manager entry scoped to elsewhere.news.
  • Ask for explicit user authorization before reading any local credential file.
  • Resolve credential paths explicitly instead of reading .env.local from an arbitrary working directory.
  • If no scoped token is available, ask the user to supply one rather than broadening the search.
  • Keep retrieved secrets out of conversational context, tool logs, and generated responses.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:93
Finding

Non-Expiring Bearer Token Is Duplicated Into Plaintext Storage and Agent Memory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 93–106
Vulnerability Type: Insecure plaintext secret persistence
Risk Level: High

bash
echo 'ELSEWHERE_API_TOKEN=THE_TOKEN' >> .env.local

The Skill additionally requires:

text
You MUST also save the token to your persistent memory/preferences
(e.g. Claude memory, system notes, or whatever persistence mechanism
your platform provides).

The suggested persistent entry includes the complete token:

text
Elsewhere API token: THE_TOKEN (for publishing articles to elsewhere.news)

Technical Analysis

The Skill duplicates a bearer credential into two plaintext persistence locations. The shell command does not set restrictive permissions, verify ownership, prevent symlink traversal, ensure exclusion from version control, or avoid duplicate entries.

Saving the same secret in general Agent memory creates a second, less controlled exposure surface. Agent memory is not an appropriate secret store because it may be surfaced in later conversations, included in exports or diagnostics, accessed by other Skills, or retained without normal credential-management controls.

The document states that the API token never expires. Consequently, accidental disclosure remains useful to an attacker until the user manually regenerates it.

Attack Path

  1. Registration completes and returns an API token.
  2. The Agent appends the complete token to .env.local.
  3. The Agent also writes the complete token into persistent memory or notes.
  4. The file is committed, backed up, logged, read by another local process, or exposed through a symlink; alternatively, another session or Skill retrieves the memory entry.
  5. An attacker uses the token as a bearer credential against the Elsewhere API.

Impact Assessment

A compromised token can authorize operations available to the creator account, including publishing or overwriting articles, upl ...[truncated 311 chars]

Remediation
View remediation

Remediation Suggestions

  • Store the token only in an operating-system keychain or dedicated secret manager.
  • Do not save credentials in Agent memory, preferences, general notes, or conversation history.
  • Obtain explicit user consent before persisting any credential.
  • If file storage is unavoidable, create a service-specific file with mode 0600 under a private configuration directory.
  • Set a restrictive umask, validate file ownership, reject symbolic links, and update the credential atomically.
  • Ensure credential files are excluded from source control, backups, diagnostics, and logs.
  • Prefer short-lived, revocable, least-privilege tokens rather than non-expiring bearer credentials.
  • Provide a clear token-revocation and rotation procedure.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:194
Finding

Predictable Shared Temporary Files Permit Content Disclosure and Symlink Attacks

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 194–215, 379–456, and 488–571
Vulnerability Type: Unsafe temporary-file handling
Risk Level: High

Article payloads are written to a fixed path:

bash
cat > /tmp/article.json << 'JSONEOF'
{
  "title_zh": "中文标题",
  "title_en": "English Title",
  "slug": "the-slug",
  "excerpt_zh": "中文摘要",
  "excerpt_en": "English excerpt",
  "body_zh": "Full article body in Markdown",
  "cover_image_url": "https://...uploaded-cover-url...",
  "ai_summary": "约100字的中文摘要,聚焦文章的独特看点...",
  "preview_excerpt": "从正文中抽取的500-1000字精彩章节..."
}
JSONEOF

Import results are also written to predictable paths:

bash
curl -s -X POST "https://elsewhere.news/api/import" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "WECHAT_ARTICLE_URL"}' > /tmp/import_result.json

Image rescue repeatedly overwrites a shared filename:

bash
curl -s -o /tmp/img_rescue.jpg "$img_url" \
  -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
  -H "Referer: https://mp.weixin.qq.com/"

Batch operations similarly use predictable names such as:

text
/tmp/import_N.json
/tmp/article_N.json
/tmp/wechat_imgs_N.txt
/tmp/img_rescue.jpg

Technical Analysis

The Skill uses fixed filenames in a shared temporary directory without creating a private directory, setting restrictive permissions, checking ownership, rejecting symbolic links, or cleaning up after completion.

On a multi-user or otherwise untrusted local system, another process can anticipate these names. It can read unpublished content, replace input before publication, or pre-create a symbolic link so a subsequent shell redirection overwrites another file accessible to the Agent.

Reusing /tmp/img_rescue.jpg across iterations and batch operations also creates race conditions and cross-task con ...[truncated 1154 chars]

Remediation
View remediation

Remediation Suggestions

  • Create a unique private directory with mktemp -d.
  • Set umask 077 before creating any temporary files.
  • Use exclusive file creation and reject pre-existing paths and symbolic links.
  • Validate that every temporary file is owned by the current user and is a regular file.
  • Use unique filenames for every article and image rather than shared counters or fixed names.
  • Register a cleanup trap to remove the private directory on normal completion, interruption, or failure.
  • Avoid reopening temporary files by pathname where a securely created file descriptor can be retained.
  • Keep unpublished content in memory when its size and platform constraints make that safe.
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (31)

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The token-check workflow instructs the agent to search persistent memory/notes for a usable API token, effectively authorizing recovery of a reusable credential from a broad, durable context store. This is dangerous because persistent memory is often less controlled than a dedicated secret manager and may be exposed to unrelated workflows or prompts.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill instructs the agent to read .env.local and inspect environment variables for an API token, which is direct credential access. In context this is especially risky because the same flow also expands to persistent-memory searches, making the agent a credential retriever without explicit user approval for secret inspection.

Content

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

  1. 检查环境变量:如果当前 shell 已有 $ELSEWHERE_API_TOKEN,直接使用
  2. 检查 .env.local:
    bash
    cat .env.local 2>/dev/null | grep ELSEWHERE_API_TOKEN
    
  3. 检查长期记忆:搜索你的持久化记忆/笔记中是否存有 Elsewhere API token
  4. 询问人类:告诉人类"我找不到你的 Elsewhere API token,你能提供一下吗?可以在 https://elsewhere.news/dashboard/login 登录后台查看。"

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 · SKILL.md (reported line 59)May include surrounding context.

Step 2: Generate registration link

bash
curl -s -X POST "https://elsewhere.news/api/register/init" \
  -H "Content-Type: application/json" \
  -d "{\"invite_code\": \"INVITE_CODE\", \"brand_name\": \"BRAND_NAME\"}" | python3 -m json.tool

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 · SKILL.md (reported line 83)May include surrounding context.

Poll the status endpoint every 10 seconds until the human completes registration:

bash
curl -s "https://elsewhere.news/api/register/status?token=REGISTRATION_TOKEN" | python3 -m json.tool

Replace REGISTRATION_TOKEN with the token from Step 2.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Appending the API token to .env.local stores a durable secret in a plain text local file that may be broadly readable by other tools, processes, backups, or later sessions. Combined with the claim that the token never expires, compromise of this file can lead to long-term account misuse.

Content

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

5a. Save to file:

bash
echo 'ELSEWHERE_API_TOKEN=THE_TOKEN' >> .env.local

5b. Save to your long-term memory:

Ssd 3

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The skill not only stores the user's API token in persistent memory/system notes but also treats that as an expected retrieval source for future sessions. A non-expiring API token preserved in long-term memory materially increases the chance of unauthorized disclosure and reuse, especially if any later prompt or tool can access that memory.

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 · SKILL.md (reported line 160)May include surrounding context.

Upload from URL (for images from WeChat, Feishu, etc.):

bash
curl -s -X POST "https://elsewhere.news/api/upload" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/image.jpg"}' | python3 -m json.tool

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 · SKILL.md (reported line 169)May include surrounding context.

Upload local file:

bash
curl -s -X POST "https://elsewhere.news/api/upload" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -F "file=@/path/to/image.jpg" | python3 -m json.tool

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 · SKILL.md (reported line 212)May include surrounding context.

Then send:

bash
curl -s -X POST "https://elsewhere.news/api/articles" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @/tmp/article.json | python3 -m json.tool

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 · SKILL.md (reported line 235)May include surrounding context.

Step 2: Import the article

bash
curl -s -X POST "https://elsewhere.news/api/import" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "WECHAT_ARTICLE_URL"}' | python3 -m json.tool

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 · SKILL.md (reported line 378)May include surrounding context.

bash
# Save import result
curl -s -X POST "https://elsewhere.news/api/import" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "WECHAT_ARTICLE_URL"}' > /tmp/import_result.json

External Script Fetching

High
Category
Supply Chain
Confidence
93% confidence
Finding

The skill instructs the agent to fetch arbitrary image URLs extracted from imported content and then re-upload them, which creates a generic URL-fetching capability. Although framed as image rescue, this can be abused for unvalidated outbound requests to attacker-controlled hosts, enabling SSRF-like behavior, internal network probing (depending on runtime network access), or transfer of sensitive bearer-authorized uploads based on untrusted content.

Content

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

md
# Download each locally and re-upload
if [ -s /tmp/wechat_imgs.txt ]; then
  while IFS= read -r img_url; do
    curl -s -o /tmp/img_rescue.jpg "$img_url" \
      -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
      -H "Referer: https://mp.weixin.qq.com/"

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 · SKILL.md (reported line 489)May include surrounding context.

3a. Import and save to file immediately

bash
curl -s -X POST "https://elsewhere.news/api/import" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"url\": \"WECHAT_URL\"}" > /tmp/import_N.json

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 · SKILL.md (reported line 537)May include surrounding context.

md
print('slug:', slug)
"

curl -s -X POST "https://elsewhere.news/api/articles" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @/tmp/article_N.json | python3 -m json.tool

External Script Fetching

High
Category
Supply Chain
Confidence
93% confidence
Finding

As in the single-import flow, the batch flow fetches attacker-influenced image URLs and re-uploads the results. In batch mode the risk is amplified because multiple arbitrary URLs may be fetched automatically, increasing the opportunity for SSRF-style abuse or unwanted interaction with attacker-controlled infrastructure.

Content

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

md
if [ -s /tmp/wechat_imgs_N.txt ]; then
  while IFS= read -r img_url; do
    curl -s -o /tmp/img_rescue.jpg "$img_url" \
      -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
      -H "Referer: https://mp.weixin.qq.com/"
    new_url=$(curl -s -X POST "https://elsewhere.news/api/upload" \

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 · SKILL.md (reported line 607)May include surrounding context.

Step 2: View current profile (optional)

bash
curl -s "https://elsewhere.news/api/profile" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" | python3 -m json.tool

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 · SKILL.md (reported line 616)May include surrounding context.

Only include the fields the user wants to change:

bash
curl -s -X PATCH "https://elsewhere.news/api/profile" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name_zh": "新名称", "bio_zh": "一句话简介", "podcast_rss_url": "https://..."}' | python3 -m json.tool

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 · SKILL.md (reported line 632)May include surrounding context.

If the user set podcast_rss_url, trigger podcast sync:

bash
curl -s -X POST "https://elsewhere.news/api/sync/podcasts" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" | python3 -m json.tool

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The token-discovery flow tells the agent to read .env.local and search persistent memory/notes for an API token without a user-facing warning that sensitive credentials are being accessed. This normalizes credential harvesting behavior and may surprise users who did not intend the agent to inspect local secret files or memory stores for this task.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 59)May include surrounding context.

Step 2: Generate registration link

bash
curl -s -X POST "https://elsewhere.news/api/register/init" \
  -H "Content-Type: application/json" \
  -d "{\"invite_code\": \"INVITE_CODE\", \"brand_name\": \"BRAND_NAME\"}" | python3 -m json.tool

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to persist an API token in long-term memory, creating durable storage of a reusable secret outside the immediate task context. This increases the blast radius of compromise, enables unintended reuse across sessions, and may expose credentials to other tools, prompts, or future interactions that can access persistent memory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill directs the agent to save a sensitive API token to persistent memory without clearly warning the user that this creates long-lived secret retention beyond the immediate workflow. Even if intended for convenience, storing secrets without explicit informed consent can violate user expectations and privacy boundaries.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 160)May include surrounding context.

Upload from URL (for images from WeChat, Feishu, etc.):

bash
curl -s -X POST "https://elsewhere.news/api/upload" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/image.jpg"}' | python3 -m json.tool

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 212)May include surrounding context.

Then send:

bash
curl -s -X POST "https://elsewhere.news/api/articles" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @/tmp/article.json | python3 -m json.tool

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 537)May include surrounding context.

Then send:

bash
curl -s -X POST "https://elsewhere.news/api/articles" \
  -H "Authorization: Bearer $ELSEWHERE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @/tmp/article.json | python3 -m json.tool

Static analysis

No suspicious patterns detected.