Back to skill

Security audit

Semantic Paper Radar

Security checks for vulnerabilities and agentic risk

Overview

This literature-search skill is mostly purpose-aligned, but its optional HTML report can include unsafe unescaped content from user queries or search results.

Install only if you are comfortable sending research queries to arXiv, OpenAlex, and PubMed. Avoid using confidential project names in queries, and avoid --export-html for untrusted topics/results until the HTML escaping and HTTPS issues are fixed; if exporting, write only to a safe workspace path and inspect the file before opening it in a browser.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/paper_radar.py:327
Finding
Unescaped User Input and Remote Metadata in Exported HTML Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/paper_radar.py`, lines 327-354 **Vulnerability Type**: HTML injection and unsafe link generation **Risk Level**: Medium ### Vulnerable Code ```python def md_to_simple_html(md_text, title="Semantic Paper Radar Report"): lines = md_text.splitlines() out = [] out.append("<!doctype html><html><head><meta charset='utf-8'>") out.append(f"<title>{title}</title>") out.append("<style>body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Arial,sans-serif;max-width:980px;margin:24px auto;padding:0 16px;line-height:1.6}h1,h2{line-height:1.3}code{background:#f2f2f2;padding:2px 4px;border-radius:4px}a{color:#0969da;text-decoration:none}a:hover{text-decoration:underline}ul{padding-left:22px}.muted{color:#666}</style></head><body>") link_pat = re.compile(r"\[([^\]]+)\]\(([^\)]+)\)") def conv_links(t): return link_pat.sub(lambda m: f'<a href="{m.group(2)}" target="_blank" rel="noopener noreferrer">{m.group(1)}</a>', t) in_list = False for ln in lines: ln = ln.rstrip() if not ln: if in_list: out.append("</ul>") in_list = False continue if ln.startswith("# "): if in_list: out.append("</ul>"); in_list=False out.append(f"<h1>{conv_links(ln[2:])}</h1>") elif ln.startswith("## "): if in_list: out.append("</ul>"); in_list=False out.append(f"<h2>{conv_links(ln[3:])}</h2>") elif ln.startswith("- "): if not in_list: out.append("<ul>"); in_list=True out.append(f"<li>{conv_links(ln[2:])}</li>") else: if in_list: out.append("</ul>"); in_list=False out.append(f"<p>{conv_links(ln)}</p>") if in_list: out.append("</ul>") out.append("<p class='muted'>Generated by semantic-paper-radar</p>") out.a ...[truncated 2656 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Escape every text node before inserting it into HTML: ```python import html safe_text = html.escape(value, quote=False) ``` 2. Escape HTML attribute values with quote escaping enabled: ```python safe_href = html.escape(url, quote=True) ``` 3. Parse link destinations with `urllib.parse.urlsplit()` and allow only explicitly approved schemes, preferably `https` and optionally `http`: ```python parsed = urllib.parse.urlsplit(url) if parsed.scheme not in {"https", "http"}: url = "" ``` 4. Escape the document title, user query, paper titles, venue names, and all other API-derived fields independently of Markdown link conversion. 5. Prefer a maintained Markdown renderer configured to: - Disable raw HTML. - Sanitize generated markup. - Reject unsafe URL schemes. - Add `rel="noopener noreferrer"` to external links. 6. Add regression tests using payloads in the query, title, venue, and URL fields, including: - HTML tags. - Quotes in link destinations. - Event-handler attributes. - `javascript:` and `data:` URLs. - Encoded or mixed-case unsafe schemes. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/paper_radar.py:45
Finding
Research Queries Transmitted to arXiv over Unencrypted HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/paper_radar.py`, lines 45-49 **Vulnerability Type**: Plaintext transmission of user-provided query data **Risk Level**: Low ### Vulnerable Code ```python def search_arxiv(query, max_results=20): q = urllib.parse.quote(query) url = ( "http://export.arxiv.org/api/query?search_query=all:%s&start=0&max_results=%d" "&sortBy=relevance&sortOrder=descending" % (q, max_results) ) ``` The URL is subsequently requested by `fetch_text()`: ```python def fetch_text(url, timeout=25): req = urllib.request.Request(url, headers={"User-Agent": "semantic-paper-radar/0.1"}) with urllib.request.urlopen(req, timeout=timeout) as r: return r.read().decode("utf-8", errors="replace") ``` ### Technical Analysis The arXiv API endpoint uses the plaintext `http` scheme. The natural-language research query is placed in the request URL and transmitted without transport encryption. Although a research topic is not inherently a secret, users may submit confidential project names, unreleased research subjects, medical topics, or other sensitive interests. Network intermediaries can observe the URL and query. Plaintext transport also provides no reliable integrity protection, allowing an active network attacker to alter the returned XML. Modified arXiv metadata is consumed without authentication and then included in JSON, Markdown, or HTML output. When combined with the unsafe HTML generation issue, manipulated metadata could be used to introduce malicious report content. Sending a query to literature APIs is necessary for the declared retrieval functionality. However, plaintext transport is not the minimum safe privilege or disclosure level required to perform that function. ### Attack Path 1. A user invokes `search` or `report` with a natural-language query. 2. `search_arxiv()` URL-encodes the query and places it in an HTTP URL. 3. The request crosses the local network and inter ...[truncated 985 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the plaintext endpoint with the supported HTTPS endpoint: ```python url = ( "https://export.arxiv.org/api/query?search_query=all:%s&start=0&max_results=%d" "&sortBy=relevance&sortOrder=descending" % (q, max_results) ) ``` 2. Ensure redirects cannot silently downgrade the connection from HTTPS to HTTP. Validate the final response URL and reject non-HTTPS schemes. 3. Retain normal TLS certificate and hostname verification; do not install permissive SSL contexts. 4. Document that research queries are transmitted to arXiv, OpenAlex, and, for biomedical searches, PubMed. 5. Consider avoiding sensitive query values in logs and exception messages. 6. Treat all API responses as untrusted even when TLS is used. Escape output correctly and validate URLs before including remote metadata in HTML reports. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared skill purpose focuses on literature discovery, but the workflow also writes HTML files to disk and references optional Scholar integration that is not implemented in the provided artifact. This mismatch undermines informed consent and reviewability: users may trigger filesystem side effects or depend on capabilities that were not transparently declared or validated.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- 阅读顺序(先读3篇)
   - 可选下一步(细分子方向)

## Output Rules

- Prefer OpenAlex entries with DOI/citation metadata for "经典" judgement.
- Keep arXiv entries for "最新前沿" and unreviewed but high-momentum work.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill instructs use of networked retrieval and optional HTML export, but it declares no explicit tool scope or permissions. That creates an authorization ambiguity where an agent may invoke broader network or file-write capabilities than a reviewer or user would reasonably expect, increasing the risk of unintended data access or local file modification.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The instruction "Present results in Chinese unless user asked otherwise" imposes a specific language by default. This is a natural-language policy concern because it forces a locale choice unless the user explicitly overrides it, rather than offering a neutral default or opt-in.

External Transmission

Medium
Category
Data Exfiltration
Content
filt.append(f"from_publication_date:{from_year}-01-01")
    filter_part = "&filter=" + urllib.parse.quote(",".join(filt)) if filt else ""
    url = (
        f"https://api.openalex.org/works?search={q}&per-page={max_results}{filter_part}"
        "&sort=relevance_score:desc"
    )
    data = fetch_json(url)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code hardcodes Chinese natural-language strings for paper classification and report generation, such as section titles and reading guidance, regardless of user preference. The policy requires avoiding forced language or locale constraints unless there is explicit opt-in or clear justification, which is not present here.

Context-Inappropriate Capability

Low
Confidence
83% confidence
Finding
The manifest describes semantic literature discovery, recommendations, reading lists, and academic context synthesis across scholarly sources. Writing an HTML report to an arbitrary local path is an extra filesystem-output capability beyond the core retrieval and synthesis behavior, and the manifest does not mention local file generation/export.

Missing User Warnings

Low
Confidence
81% confidence
Finding
This code creates and writes an HTML report file when --export-html is used, but there is no inline comment or docstring warning that the skill performs a filesystem write. For code-file warning checks, file writes should have some disclosure unless clearly covered; here the CLI flag implies export, but the safety disclosure is still minimal.

Static analysis

No suspicious patterns detected.