Back to skill

Security audit

文献综述自动器

Security checks for vulnerabilities and agentic risk

Overview

This literature-review skill is purpose-aligned overall, but it has risky optional LLM configuration that can send an API key and research content to any configured endpoint.

Review this before installing if you may use LLM writing with real API keys or confidential research topics. Keep use_llm_for_writing disabled unless you trust the configured provider, do not pass API keys with arbitrary llm_api_base values, prefer a sandboxed virtual environment, and avoid using sensitive or unpublished research queries because they are sent to third-party academic services.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
main.py:225
Finding

Unvalidated LLM Endpoint Can Exfiltrate Bearer Credentials and Research Data

Content
View full analysis
Warning: No LLM API key is configured; using the local template." paper_summaries = "\n".join([ f"- {p['title']} ({p.get('year','')}): {p.get('abstract','No abstract')[:200]}..." for p in papers[:15] ]) headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = { "model": config.get("llm_model"), "messages": [{"role": "user", "content": prompt}], "temperature": 0.3 } api_base = config.get("llm_api_base") try: resp = requests.post( f"{api_base}/chat/completions", headers=headers, json=data, timeout=60 ) ``` The endpoint value originates from command-line JSON without validation: ```python config = DEFAULT_CONFIG.copy() if args.config: try: user_config = json.loads(args.config) config.update(user_config) except: pass ``` ### Technical Analysis The `llm_api_base` setting is accepted from the `--config` argument and merged directly into the runtime configuration. When LLM writing is enabled, the application sends the configured API key in an `Authorization: Bearer` header to that endpoint. There is no hostname allowlist, HTTPS enforcement, URL-scheme validation, or binding between an API key and its intended provider. An attacker who can influence the command invocation or supplied configuration can therefore redirect a credential-bearing request to an arbitrary server. The request body also contains the user-supplied research topic and externally retrieved paper titles and abstracts. Consequently, exploitation can disclose both the credential and ...[truncated 1308 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
main.py:229
Finding

External Publication Metadata Is Embedded Directly into an Instruction-Bearing LLM Prompt

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:67
Finding

arXiv Queries and Responses Use Unencrypted HTTP

Content
View full analysis
List[Dict]: """Call the arXiv API.""" url = "http://export.arxiv.org/api/query" params = { "search_query": f"all:{query}", "start": 0, "max_results": limit, "sortBy": "relevance", "sortOrder": "descending" } try: resp = requests.get(url, params=params, timeout=10) resp.raise_for_status() ``` The alternate implementation parses data received through the same plaintext transport: ```python url = "http://export.arxiv.org/api/query" response = self.session.get(url, params=params, timeout=30) response.raise_for_status() root = ET.fromstring(response.text) ``` ### Technical Analysis The arXiv API is accessed through `http://`, so TLS does not protect either the query parameters or the returned Atom feed. Network intermediaries can observe the research query and alter the response in transit. Although the declared `main.py` implementation currently discards the arXiv response, `lit_review.py` parses the response into paper records and uses their titles, abstracts, authors, DOI values, and URLs in ranking and generated reports. The standalone test also parses an unencrypted response. A timeout and `raise_for_status()` only address availability and HTTP status handling. They do not provide confidentiality, server authentication, or response integrity. ### Attack Path 1. The victim runs the Skill on a network controlled or observable by an attacker. 2. The Skill sends the research query to the arXiv endpoint over plaintext HTTP. 3. The attacker observes the query or intercepts the server response. 4. For `lit_review.py`, the attacker s ...[truncated 674 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Broad Unpinned Dependency Ranges Make Installation Non-Reproducible

Content
View full analysis
=2.28.0 scikit-learn>=1.0.0 numpy>=1.21.0 sentence-transformers>=2.0.0 bertopic>=0.12.0 python-docx>=0.8.11 ``` The documentation also recommends unconstrained direct installation: ```bash pip install requests pip install scikit-learn numpy pip install sentence-transformers bertopic pip install python-docx ``` ### Technical Analysis Every dependency uses a broad lower-bound constraint, and the documentation permits installation with no version constraint at all. There is no lockfile, hash verification, or documented trusted package index. As a result, identical installations performed at different times can resolve to different direct and transitive dependency versions. This increases exposure to compromised future releases, malicious dependency-chain changes, incompatible updates, or newly introduced vulnerabilities. The reviewed package names do not exhibit an evident typosquatting pattern, and no malicious dependency was confirmed. The issue is the unsafe and non-reproducible installation policy. ### Attack Path 1. A direct or transitive dependency publishes a compromised or vulnerable future release that still satisfies the lower-bound requirement. 2. A user installs the project dependencies with `pip install -r requirements.txt` or follows the unconstrained documentation commands. 3. The resolver selects the affected release. 4. Package build or installation logic executes in the user’s environment, or the compromised package is later imported by the Skill. 5. The dependency receives the privileges of the Python installation or Skill process. ### Impact Assessment Impact depends on the behavior of a compromised dependency and the privileges used during installa ...[truncated 366 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (40)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad natural-language terms such as “文献综述”, “检索文献”, and “研究热点”, which can overlap with ordinary user requests and cause the skill to activate when the user did not explicitly intend to run it. Because this skill performs network retrieval and can generate/write review output, accidental invocation could lead to unintended external requests or undesired content generation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The title and the entire document are presented in Chinese, and there is no indication that the user opted into Chinese or that the skill is intended only for a Chinese-language or region-specific context. This creates a natural-language policy concern because it implicitly fixes the output language rather than offering a choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring presents the skill entirely in Chinese, and the rest of the tool's prompts and usage messages are also Chinese-only. This imposes a specific language on users without any opt-in or documented regional justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The skill sends user-provided research queries to Semantic Scholar over the network, which is an external data transmission. While expected for a literature search tool, this can leak sensitive or proprietary research interests, internal project names, or confidential topics if used in enterprise or regulated contexts.

Content

Scanner excerpt · lit_review.py (reported line 135)May include surrounding context.

python
def search_semantic_scholar(self, keywords: str, years: int, limit: int = 50) -> List[Dict]:
        """从Semantic Scholar检索文献"""
        print("\n📚 正在检索 Semantic Scholar...")
        url = "https://api.semanticscholar.org/graph/v1/paper/search"
        current_year = datetime.now().year
        
        params = {

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The skill transmits search queries to CrossRef, exposing user-supplied topics to an external service. In this skill’s context, outbound search is core functionality, but it still creates privacy and data-governance risk if users enter confidential research topics or sensitive terms.

Content

Scanner excerpt · lit_review.py (reported line 238)May include surrounding context.

python
def search_crossref(self, keywords: str, years: int, limit: int = 30) -> List[Dict]:
        """从CrossRef检索文献"""
        print("\n📑 正在检索 CrossRef...")
        url = "https://api.crossref.org/works"
        current_year = datetime.now().year
        
        params = {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script writes generated content to any user-supplied output path without validation, restriction, or confirmation. In an agent or automated environment, this can overwrite arbitrary files writable by the process, causing data loss or clobbering configuration, especially if an untrusted prompt or workflow controls the path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

User-facing strings, comments, and generated content are written exclusively in Chinese, and the review generator instructs the model in Chinese with no language-selection mechanism. This creates a language-policy issue when the skill implicitly fixes the interaction/output locale instead of offering the user a choice or documenting a justified locale restriction.

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 · config.json (reported line 6)May include surrounding context.

json
"max_papers": 50,
    "use_llm_for_writing": False,
    "llm_model": "deepseek-chat",
    "llm_api_base": "https://api.deepseek.com/v1",
    "output_format": "markdown",
    "human_review_papers": False
}

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 · lit_review.py (reported line 46)May include surrounding context.

python
"max_papers": 50,
    "use_llm_for_writing": False,
    "llm_model": "deepseek-chat",
    "llm_api_base": "https://api.deepseek.com/v1",
    "output_format": "markdown",
    "human_review_papers": False
}

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 · main.py (reported line 29)May include surrounding context.

python
"max_papers": 50,
    "use_llm_for_writing": False,
    "llm_model": "deepseek-chat",
    "llm_api_base": "https://api.deepseek.com/v1",
    "output_format": "markdown",
    "human_review_papers": False
}

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 · main.py (reported line 37)May include surrounding context.

python
# ------------------- 检索模块 -------------------
def search_semantic_scholar(query: str, year_start: int, year_end: int, limit: int = 100) -> List[Dict]:
    """调用Semantic Scholar API"""
    url = "https://api.semanticscholar.org/graph/v1/paper/search"
    params = {
        "query": query,
        "year": f"{year_start}-{year_end}",

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 79)May include surrounding context.

md
# ------------------- 检索模块 -------------------
def search_semantic_scholar(query: str, year_start: int, year_end: int, limit: int = 100) -> List[Dict]:
    """调用Semantic Scholar API"""
    url = "https://api.semanticscholar.org/graph/v1/paper/search"
    params = {
        "query": query,
        "year": f"{year_start}-{year_end}",

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

L66 的文档说明该函数会调用 arXiv API,只是年份过滤需要额外处理;但 L78-L80 的注释和返回值表明响应根本未被解析,函数在成功请求后直接返回空列表。对于技能宣称支持 arXiv 检索而言,这种文档与实际行为存在明显偏差。

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 · main.py (reported line 87)May include surrounding context.

python
def search_crossref(query: str, year_start: int, year_end: int, limit: int = 50) -> List[Dict]:
    """调用CrossRef API"""
    url = "https://api.crossref.org/works"
    params = {
        "query": query,
        "filter": f"from-pub-date:{year_start},until-pub-date:{year_end}",

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 81)May include surrounding context.

md
def search_crossref(query: str, year_start: int, year_end: int, limit: int = 50) -> List[Dict]:
    """调用CrossRef API"""
    url = "https://api.crossref.org/works"
    params = {
        "query": query,
        "filter": f"from-pub-date:{year_start},until-pub-date:{year_end}",

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

L168-L170 的文档明确描述该函数基于标题和摘要关键词共现并使用 KMeans 进行聚类,但实际代码在 L174-L178 仅构造两个固定主题并按文献列表位置切分 papers,没有执行任何关键词分析或聚类算法。这不是单纯实现细节省略,而是文档对核心能力的描述与代码行为直接不符。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

When LLM writing is enabled, the skill sends paper titles and abstract excerpts to a third-party API without a clear runtime disclosure or consent gate. In a literature-review context this may seem routine, but queries, curated selections, and proprietary or sensitive research topics can still leak to an external service, creating confidentiality and compliance risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The code transmits composed prompts containing topic, cluster labels, and paper metadata/abstract snippets to a configurable external LLM endpoint. Because the endpoint is user-configurable and there is no validation, disclosure, or trust control, this can leak research inputs to unintended third parties and increases risk if an untrusted base URL is supplied.

Content

Scanner excerpt · main.py (reported line 249)May include surrounding context.

python
}
    api_base = config.get("llm_api_base")
    try:
        resp = requests.post(f"{api_base}/chat/completions", headers=headers, json=data, timeout=60)
        resp.raise_for_status()
        result = resp.json()
        content = result["choices"][0]["message"]["content"]

Tainted flow: 'data' from requests.get (line 97, network input) → requests.post (network output)

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 · main.py (reported line 249)May include surrounding context.

python
}
    api_base = config.get("llm_api_base")
    try:
        resp = requests.post(f"{api_base}/chat/completions", headers=headers, json=data, timeout=60)
        resp.raise_for_status()
        result = resp.json()
        content = result["choices"][0]["message"]["content"]

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

L014“写一篇综述”和 L015“研究热点”都是高频、宽泛的自然语言短语,未限定学术文献检索或特定使用场景,容易覆盖普通对话中的常见请求。文档也没有提供排除条件、负例或更窄的触发边界来说明何时应当激活该技能。

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The configurable external LLM endpoint enables transmission of generated drafts and source abstracts to a third-party API. In this skill context, that is expected functionality, but it still represents a genuine data exfiltration surface if users process confidential research notes, unpublished ideas, or licensed content without clear consent and endpoint restrictions.

Content

Scanner excerpt · skill.md (reported line 43)May include surrounding context.

md
description: 大模型名称(需配置API密钥)
  - name: llm_api_base
    type: str
    default: https://api.deepseek.com/v1
    description: 大模型API端点
  - name: output_format
    type: str

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill states that locally generated drafts and paper abstracts may be sent to an external LLM API, but the description does not prominently warn users about this outbound data transfer. This creates a real privacy and data-governance risk because user research topics, curated paper sets, and generated drafts may contain sensitive or proprietary information that is transmitted to third-party services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code hard-codes Chinese-language request text and user-facing output strings, implying the skill operates in a specific language without offering a user choice. That is a natural-language locale policy concern because the file gives no indication that Chinese output is optional or required for a justified region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script prints user-facing status messages entirely in Chinese (状态码, 检索到, 标题) with no option to select language or any documented reason for a Chinese-only locale. This creates a natural-language policy issue because the skill imposes a specific language on users rather than offering choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.