Back to skill

Security audit

sn-search-academic

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an academic research tool, but its crawler fallback uses disguised browser automation and exposes the full host environment to that browser process.

Install and run this only in an isolated environment without cloud keys, repo tokens, or other sensitive environment variables. Prefer the official API providers and avoid the Camoufox crawler fallback unless you intentionally accept browser-automation and site-policy risk. Pin dependencies before production use, and assume your search queries, paper IDs, titles, optional email identifiers, and API keys may be sent to the selected academic services.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/arxiv_crawler_search.py:143
Finding

Full Host Environment Inherited by Third-Party Crawler Browser Processes

Content
View full analysis

Vulnerability Details

File Location: scripts/arxiv_crawler_search.py:143-149
Vulnerability Type: Excessive environment-variable exposure to a child process
Risk Level: Medium

Vulnerable Code

python
options = camoufox_launch_options(headless=headless)
playwright = await async_playwright().start()
browser = await playwright.firefox.launch(
    executable_path=options["executablePath"],
    headless=options.get("headless", headless),
    args=options.get("args") or [],
    env={**os.environ, **(options.get("env") or {})},
    firefox_user_prefs=options.get("firefoxUserPrefs") or {},
    proxy=options.get("proxy") or None,
)

Technical Analysis

The crawler forwards the complete host environment to a browser executable whose path and launch options are supplied by the external camoufox-js dependency. Academic crawling does not require unrelated environment variables such as cloud credentials, CI tokens, database passwords, or API keys for other services.

This violates least privilege by making every inherited environment variable readable by the browser process. The code does not itself transmit those values, so exploitation depends on a compromised, malicious, or substituted Camoufox/browser component.

Attack Path

  1. An attacker compromises the installed camoufox-js package, its generated configuration, or the browser executable it selects.
  2. The official academic provider fails, causing the crawler fallback to run, or the crawler is invoked directly.
  3. camoufox-js supplies an attacker-controlled or compromised executablePath.
  4. Playwright starts that executable with env={**os.environ, ...}.
  5. The child process reads unrelated credentials from its inherited environment.
  6. Because the browser already requires network access, a malicious executable can transmit those credentials externally.

Impact Assessment

A compromised child process can read every environment variable available to the parent Agent proc ...[truncated 434 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace full environment inheritance with a minimal allowlist containing only variables required to launch the browser, such as PATH, selected locale variables, and explicitly documented browser settings.
  • Never pass unrelated API keys, cloud credentials, CI variables, or database secrets to crawler processes.
  • Validate and canonicalize options["executablePath"]; require it to resolve to an approved browser installation.
  • Run crawler fallbacks in a sandbox or container with restricted filesystem access, a sanitized environment, and destination-limited network egress.
  • Pin and verify the camoufox-js package and browser artifacts.
  • Add an automated test asserting that sensitive environment variables are absent from the child-process environment.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/semantic_scholar_crawler_refTree.py:174
Finding

Full Host Environment Inherited by Semantic Scholar Crawler Process

Content
View full analysis

Vulnerability Details

File Location: scripts/semantic_scholar_crawler_refTree.py:174-180
Vulnerability Type: Excessive environment-variable exposure to a child process
Risk Level: Medium

Vulnerable Code

python
options = camoufox_launch_options(headless=headless)
playwright = await async_playwright().start()
browser = await playwright.firefox.launch(
    executable_path=options["executablePath"],
    headless=options.get("headless", headless),
    args=options.get("args") or [],
    env={**os.environ, **(options.get("env") or {})},
    firefox_user_prefs=options.get("firefoxUserPrefs") or {},
    proxy=options.get("proxy") or None,
)

Technical Analysis

The Semantic Scholar citation crawler starts a browser process using launch options generated by the third-party camoufox-js component and passes the complete parent environment to that executable.

Citation-tree crawling requires browser and networking configuration but does not require access to all secrets held in the Agent's environment. The broad inheritance therefore exceeds the minimum privileges necessary for the declared functionality.

The audited code does not explicitly exfiltrate environment variables. Exploitation requires a compromised dependency, substituted executable, or malicious browser component.

Attack Path

  1. An attacker compromises or substitutes camoufox-js, its launch-option output, or the selected browser executable.
  2. The official Semantic Scholar citation provider fails, triggering the crawler fallback, or the crawler is run directly.
  3. The crawler launches the selected executable with the complete os.environ.
  4. The malicious child process enumerates inherited environment variables.
  5. It extracts useful credentials and transmits them using its permitted network access.

Impact Assessment

The crawler process can access all environment variables visible to the parent process, not merely Semantic Scholar configuration. Potentially e ...[truncated 349 chars]

Remediation
View remediation

Remediation Suggestions

  • Construct a fresh child-process environment from an explicit allowlist rather than merging os.environ.
  • Exclude credentials and tokens unrelated to browser operation.
  • Verify that the executable path returned by camoufox-js belongs to an approved installation directory and is not writable by untrusted users.
  • Isolate crawler execution in a sandbox with no ambient credentials and narrowly restricted network destinations.
  • Pin and integrity-check the Node package and browser executable.
  • Prefer the official Semantic Scholar API and make crawler fallback explicit or opt-in where practical.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-7
Vulnerability Type: Non-reproducible dependency resolution without integrity verification
Risk Level: Medium

Vulnerable Code

text
httpx>=0.27
arxiv>=2.0.0
beautifulsoup4>=4.12.3
semanticscholar
pypdf>=4.0.0
playwright>=1.40.0
deepxiv-sdk

The documented installation command in SKILL.md:43-45 is:

bash
python3 -m pip install -r requirements.txt

Technical Analysis

All dependencies permit future releases, while semanticscholar, playwright, and deepxiv-sdk have no upper or exact version constraint. No hashes or lock file are present. Consequently, installing the Skill later may resolve package versions different from those reviewed during this audit.

This is a supply-chain weakness rather than evidence that any listed package is currently malicious. The concern is amplified because these packages are imported into the Agent process, perform network operations, launch browser components, or manage service tokens.

Attack Path

  1. An upstream package account, release pipeline, or transitive dependency is compromised.
  2. A malicious version satisfying the broad requirement is published.
  3. A user follows the documented pip install -r requirements.txt command.
  4. The resolver installs the malicious version because no exact version or trusted hash prevents it.
  5. Malicious installation-time or import-time code executes with the permissions and environment of the user running the Skill.
  6. The package can access local files, inherited credentials, and the network within that user's security context.

Impact Assessment

A compromised dependency can execute arbitrary Python code with the privileges of the installing or invoking user. It could read accessible files and environment variables, modify Skill behavior, intercept academic queries and credentials, or transmit data over the network.

The actual impact depends on the runtime account and its accessi ...[truncated 194 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin every direct dependency to an exact reviewed version.
  • Generate a reproducible lock file that includes transitive dependencies.
  • Require cryptographic hashes during installation, for example with pip's --require-hashes.
  • Use a trusted package index or controlled internal mirror.
  • Regularly scan locked dependencies for known vulnerabilities and review upgrades before changing pins.
  • Install dependencies in an isolated virtual environment or container under a low-privilege account.
  • Separately pin and integrity-verify Node packages, Playwright browser artifacts, and Camoufox components.
  • Avoid automatic SDK token registration unless it is explicitly required and its network behavior has been reviewed.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 (65)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

描述声称该技能可用于“学术调研、论文精读、相关工作梳理、百科知识查询和引用链追溯”。但给出的代码块实际只封装了 arXiv 搜索接口:构造查询、按字段搜索、按 ID 获取论文元数据,以及一个隐藏的 download_pdf 接口用于下载 PDF 文件。这里存在两类明显不一致:第一,代码具有未在描述中体现的本地文件写入/下载能力(download_pdf 会创建目录并保存 PDF),属于实质性额外能力;第二,描述中的“百科知识查询”和“引用链追溯”在代码中没有对应实现,代码既不访问百科类资源,也不解析引用关系或追踪 citation chain。虽然“学术调研、论文精读、相关工作梳理”可部分由 arXiv 检索支持,但整体描述比实际实现更宽泛,且遗漏了下载能力,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

该代码块的实际功能较窄:它向指定语言的 Wikipedia API 发起搜索请求,并将搜索结果格式化输出。这与声明中的“百科知识查询”基本一致,但声明同时包含“学术调研、论文精读、相关工作梳理、引用链追溯”等更强或不同类型的能力。代码中没有论文内容获取、学术数据库访问、参考文献解析、引用关系追踪或综述生成等实现,因此声明明显超出了实际行为范围,属于描述与行为不一致。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本技能的 `scripts/...`、`requirements.txt`、`references/...` 路径均相对本 skill 目录;若当前工作目录不同,先解析为绝对路径,不要依赖 `${SKILL_DIR}` 运行时变量。

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/arxiv_crawler_search.py (reported line 148)May include surrounding context.

python
executable_path=options["executablePath"],
        headless=options.get("headless", headless),
        args=options.get("args") or [],
        env={**os.environ, **(options.get("env") or {})},
        firefox_user_prefs=options.get("firefoxUserPrefs") or {},
        proxy=options.get("proxy") or None,
    )

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/semantic_scholar_crawler_refTree.py (reported line 179)May include surrounding context.

python
executable_path=options["executablePath"],
        headless=options.get("headless", headless),
        args=options.get("args") or [],
        env={**os.environ, **(options.get("env") or {})},
        firefox_user_prefs=options.get("firefoxUserPrefs") or {},
        proxy=options.get("proxy") or None,
    )

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to use shell, network, environment-sourced credentials, and file output, but it does not declare any explicit tool scope such as allowed-tools or permissions. That omission weakens least-privilege controls and makes it easier for an agent runtime to overgrant capabilities, especially because the workflow includes external network access and writing result files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest description and title are written entirely in Chinese, signaling a fixed language/locale for the skill experience. The file does not offer a user language choice or explain that the skill is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation describes fallback use of external providers, including HTTP API access and a crawler, without clearly warning users that paper IDs, titles, and related query metadata may be transmitted to third-party services. In an academic research workflow, queries can reveal sensitive interests, unpublished topics, or proprietary investigation directions, so silent fallback to external services creates a meaningful privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The crawler deliberately invokes camoufox-js to generate disguised browser launch options, which adds anti-detection and browser-spoofing behavior unrelated to normal arXiv search. In an academic-search skill, this makes the code more suspicious because it enables evasion of site detection controls and can be repurposed for stealthy scraping against other targets.

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/arxiv_crawler_search.py (reported line 114)May include surrounding context.

python
def camoufox_launch_options(headless: bool) -> dict[str, Any]:
    project_root = find_camoufox_project_root()
    try:
        raw = subprocess.check_output(
            ["node", "--input-type=module", "-e", camoufox_launch_options_script(headless=headless)],
            cwd=project_root,
            text=True,

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/semantic_scholar_crawler_refTree.py (reported line 145)May include surrounding context.

python
def camoufox_launch_options(headless: bool) -> dict[str, Any]:
    project_root = find_camoufox_project_root()
    try:
        raw = subprocess.check_output(
            ["node", "--input-type=module", "-e", camoufox_launch_options_script(headless=headless)],
            cwd=project_root,
            text=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The browser context requests geolocation permission and sets a fabricated geolocation/locale/timezone profile that is unnecessary for arXiv search. This misrepresents the client environment and can be used to evade localization-based controls or hide the true execution context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code grants geolocation permission and supplies fake coordinates without any user notice or functional need for academic search. This is deceptive browser behavior and creates unnecessary privacy and compliance risk, especially in a skill whose stated purpose does not involve location-aware operation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Forcing a specific locale and timezone without user choice is a form of client spoofing that is unnecessary for the stated academic-search purpose. While lower impact than credential theft or code execution, it contributes to deceptive automation and can help conceal the true environment from remote services.

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/arxiv_pdf_paper.py (reported line 119)May include surrounding context.

python
+ ";或安装系统工具 poppler/pdftotext 后重试。"
        )

    proc = subprocess.run(
        [binary, "-layout", "-", "-"],
        input=pdf_bytes,
        stdout=subprocess.PIPE,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes the skill as being for academic research, paper close reading, related-work review, encyclopedia lookup, and citation tracing, which aligns with search and metadata retrieval. However, this file also implements a download path that fetches a paper PDF and writes it to a local directory, which is a materially broader behavior than search/querying and is not mentioned in the manifest description.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring for download_pdf states '隐藏兼容接口,不在 skill 使用说明中公开' (hidden compatibility interface, not publicly exposed in skill usage). But main() dispatches on a literal 'download' subcommand and _main_download() builds a user-facing CLI for downloading PDFs, so the documentation directly contradicts the actual behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring presents the skill description only in Chinese, and the CLI help strings are also Chinese-only, which indicates a fixed language choice in the skill's natural-language interface. There is no visible opt-in, language selection, or documented region-specific justification in this file.

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 · scripts/crossref_search.py (reported line 14)May include surrounding context.

python
from search_utils import build_parser, get_client, make_item, make_result, print_json


API_URL = "https://api.crossref.org/works"
MAX_LIMIT = 100

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 · scripts/ssrn_search.py (reported line 19)May include surrounding context.

python
from search_utils import build_parser, get_client, make_item, make_result, print_json


API_URL = "https://api.crossref.org/works"
MAX_LIMIT = 100

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function reads a mailto value from CLI or environment variables and sends it, along with the user's search query, to the external Crossref API. While the code is functional, there is no confirmation prompt or explicit user-facing warning in this file that user input and an email identifier will be transmitted to a third-party service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring and user-facing operational notice are written only in Chinese, and the skill also emits Chinese-only dependency and error messages elsewhere. This creates a language/locale constraint without explicit user opt-in, which matches the policy category for forced language use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The parser description, argument help text, and epilog are all presented in Chinese only, while the file does not offer a user-selectable interface language for these messages. A search-result language flag exists, but it controls request headers/results rather than the user-facing locale of the skill itself.

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 · scripts/openalex_search.py (reported line 12)May include surrounding context.

python
from search_utils import build_parser, get_client, make_item, make_result, print_json


API_URL = "https://api.openalex.org/works"
MAX_LIMIT = 200
SELECT_FIELDS = ",".join(
    [

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script emits user-facing error text in Chinese (for example, unsupported source and empty ID errors) with no option to select another language or locale. This is a natural-language policy concern because the file hardcodes a specific language for interaction rather than offering user opt-in or documenting a justified locale restriction.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.