Back to skill

Security audit

arXiv Paper Digest

Security checks for vulnerabilities and agentic risk

Overview

This skill is a mostly coherent AI paper digest tool with disclosed HuggingFace network access and optional delivery automation, but its documentation overstates some features and users should treat fetched paper content as untrusted.

Install only if you are comfortable with the skill fetching public paper metadata from HuggingFace. Confirm language, timezone, recipient, and schedule before enabling any recurring QQ or Notion delivery, and do not let generated digest text trigger other agent actions without review because paper metadata is external content.

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_papers.py:56
Finding
Untrusted Remote Paper Metadata Is Propagated Without Output Safety Boundaries<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_papers.py`, lines 56–59, 113–124, and 151–185 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code Remote data is fetched and parsed without establishing a trust boundary: ```python response = requests.get(HF_PAPERS_API, timeout=20, headers={"User-Agent": USER_AGENT}) response.raise_for_status() data = response.json() ``` Fields controlled by the remote API response are copied into the internal paper representation: ```python paper = { "id": paper_data.get("id", ""), "title": paper_data.get("title", ""), "authors": [a.get("name", "") for a in paper_data.get("authors", [])], "summary": paper_data.get("summary", ""), "ai_summary": paper_data.get("ai_summary", ""), "keywords": paper_data.get("ai_keywords", []), "published": paper_data.get("publishedAt", ""), "link": f"https://arxiv.org/abs/{paper_data.get('id', '')}", "hf_link": f"https://huggingface.co/papers/{paper_data.get('id', '')}", "upvotes": paper_data.get("upvotes", 0) or 0, "num_comments": item.get("numComments", 0) or 0, "organization": paper_data.get("organization", {}).get("fullname", ""), "position": i + 1, } ``` Those fields are then inserted directly into Markdown: ```python for i, p in enumerate(papers, 1): # Trending badge badge = f"🔥 Trending #{p.get('position', '?')}" lines.append(f"## {i}. {p['title']}") lines.append(f"\n*{badge} | 👍 {p.get('upvotes', 0)} | 💬 {p.get('num_comments', 0)}*") if p.get('organization'): lines.append(f"\n**机构:** {p['organization']}") lines.append(f"\n**Authors:** {', '.join(p['authors'][:3])}" + (f" et al." if len(p['authors']) > 3 else "")) lines.append(f"\n**Links:** [arXiv]({p['link']}) | [HF]({p['hf_link']})") if p.get('keywords'): lines.append(f"\n**Keywords:** {', '.join(p['keywords'][:5])}") ...[truncated 3011 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Validate the API response schema** - Require the top-level response to be a list. - Verify that each paper entry and nested field has the expected type. - Reject or normalize unexpected objects, arrays, and excessively long strings. - Permit only expected arXiv identifier characters before constructing URLs. 2. **Escape output for its destination** - Escape Markdown control characters in titles, authors, organizations, keywords, and summaries. - Construct links only from validated identifiers. - Consider emitting plain text when rich Markdown is unnecessary. 3. **Establish explicit agent-facing trust boundaries** - Wrap external content in clearly marked delimiters. - State that enclosed paper metadata is untrusted reference data and must not be interpreted as instructions, tool requests, or policy. - Keep system instructions and retrieved content in separate message or data fields where the consuming framework supports this. 4. **Apply strict length limits** - Limit every external string field, not only summaries. - Limit collection sizes for authors and keywords. - Reject records that exceed reasonable structural limits. 5. **Harden downstream consumers** - Configure agents not to execute tools based solely on retrieved paper content. - Require explicit user confirmation for consequential actions. - Sanitize rendered Markdown and restrict unsafe URL schemes, remote images, and raw HTML. 6. **Add adversarial tests** - Test titles and summaries containing Markdown links, images, raw HTML, nested formatting, and instruction-like text. - Verify that such payloads remain inert data in both Markdown and agent-processing workflows. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list includes broad terms such as `papers`, `trending`, and `research news`, which can cause the skill to activate for generic conversations unrelated to this specific function. Over-broad invocation increases the chance of unintended network access, local file modification for history tracking, and accidental routing of user requests through this skill when another skill or no skill should be used.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
Defaulting delivery time to Beijing time and preselecting categories without explicit user opt-in can lead to unwanted scheduling behavior and assumptions about the user's locale or interests. In context, this is primarily a consent and UX safety issue rather than a direct security exploit, but it can still cause unintended automated actions such as scheduled digest delivery at the wrong time.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Preselecting Chinese (`zh`) as the default output language without requiring an explicit user choice can produce content in a language the user did not intend, which is a form of unintended behavior. In this skill's context the danger is limited, but it can still lead to misdelivery, confusion, or automated digest messages being sent in an unusable language.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module usage/docs state '--source Data source: hf (HuggingFace), arxiv' and the parser exposes the same choice, implying real support for both sources. In practice, when 'arxiv' is selected the code only prints a note and still fetches HuggingFace papers, so the documentation and interface contradict actual behavior.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The inline comment says requests is preferred because it is 'less suspicious to scanners', but the code simply performs the same outbound HTTP fetch regardless of library choice. This documentation introduces an intent implication of avoiding detection rather than explaining a legitimate implementation reason, which conflicts with the skill's stated paper-fetching purpose.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The formatter switches on `lang`, but line L173 always emits the Chinese label `机构:` regardless of the selected language. This violates the language/locale consistency policy because the skill forces a specific language fragment without user opt-in when `--lang en` is used.

Static analysis

No suspicious patterns detected.