Back to skill

Security audit

agent-daily-paper

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent arXiv digest skill, but it needs Review because it combines scheduled automation, repository write behavior, unpinned installs, plaintext arXiv queries, and optional third-party AI data sharing.

Install only if you are comfortable with scheduled local or optional GitHub automation, network queries to arXiv, and optional OpenAI processing. Prefer offline Argos translation, avoid TRANSLATE_PROVIDER=auto/openai for sensitive work, review the GitHub Actions workflow before enabling it, and pin dependencies/models if using this in a controlled environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/bootstrap_env.py:54
Finding
Unpinned Dependencies and Mutable Model Artifacts Create a Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/bootstrap_env.py:54-57` - `scripts/bootstrap_env.py:80-98` - `scripts/install_embedding_model.py:12-28` - `scripts/install_argos_model.py:54-69` - `.github/workflows/daily-digest.yml:16-27` **Vulnerability Type**: Unpinned third-party packages, models, and CI actions **Risk Level**: Medium ### Vulnerable Code ```python # scripts/bootstrap_env.py:54-57 print("[BOOTSTRAP] Installing python packages in env...") run([conda, "run", "-n", env_name, "python", "-m", "pip", "install", "--upgrade", "pip"], cwd=root) run([conda, "run", "-n", env_name, "python", "-m", "pip", "install", "argostranslate"], cwd=root) run([conda, "run", "-n", env_name, "python", "-m", "pip", "install", "sentence-transformers"], cwd=root) ``` ```python # scripts/bootstrap_env.py:80-98 if not skip_embedding_model: print("[BOOTSTRAP] Preloading embedding model (BAAI/bge-m3)...") proc = run( [conda, "run", "-n", env_name, "python", "scripts/install_embedding_model.py", "--model", "BAAI/bge-m3"], cwd=root, check=False, ) if proc.returncode != 0: print("[BOOTSTRAP][WARN] Embedding model preload failed, will download on first run.") print("[BOOTSTRAP] Preloading reranker model (BAAI/bge-reranker-v2-m3)...") proc = run( [ conda, "run", "-n", env_name, "python", "scripts/install_embedding_model.py", "--kind", "reranker", "--model", "BAAI/bge-reranker-v2-m3", ], cwd=root, check=False, ) ``` ```python # scripts/install_embedding_model.py:12-28 parser.add_argument("--model", default="BAAI/bge-m3") parser.add_argument("--kind", default="embedding", choices=["embedding", "reranker"]) args = parser.parse_args() try: from sentence_transformers import SentenceTransformer, CrossEncoder except Exception as exc: print(f"[ERROR] sentence-transformers not available: {exc}") return 1 try: if args.kind == "e ...[truncated 3800 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dependency lock file containing exact versions and cryptographic hashes for all direct and transitive Python packages. 2. Install packages with hash enforcement, for example: ```bash python -m pip install --require-hashes -r requirements.lock ``` 3. Do not upgrade `pip` implicitly during routine bootstrap. Pin and validate the required installer version separately. 4. Pin Hugging Face models to reviewed immutable commit revisions rather than floating repository heads. 5. Record and verify expected hashes for downloaded model files before loading them. 6. Select an explicit reviewed Argos package version and verify its checksum or signature before calling `install_from_path`. 7. Pin GitHub Actions to complete commit SHAs rather than `@v4` or `@v5`. 8. Reduce workflow permissions to `contents: read` by default and grant write capability only to a narrowly isolated commit step when required. 9. Consider generating digest artifacts without allowing the same dependency-processing job to push directly to the default branch. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_digest.py:42
Finding
User Research Interests Are Transmitted to arXiv over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/run_digest.py:42` - `scripts/run_digest.py:239-250` - `scripts/prepare_fields.py:24` - `scripts/prepare_fields.py:386-396` - `scripts/doctor.py:24` - `scripts/doctor.py:178-188` **Vulnerability Type**: Plaintext transmission and unauthenticated remote response handling **Risk Level**: Medium ### Vulnerable Code ```python # scripts/run_digest.py:42 ARXIV_API = "http://export.arxiv.org/api/query" ``` ```python # scripts/run_digest.py:239-250 def http_get(url: str, params: dict[str, Any], retries: int = 2) -> str: full_url = f"{url}?{urlencode(params)}" for attempt in range(retries + 1): try: req = Request(full_url, headers={"User-Agent": "agent-daily-paper/1.0"}) with urlopen(req, timeout=25) as resp: return resp.read().decode("utf-8", errors="replace") except Exception: if attempt >= retries: raise time.sleep(2 ** attempt) raise RuntimeError("unreachable") ``` ```python # scripts/run_digest.py:253-265 def fetch_arxiv_papers(search_query: str, source_field: str, max_results: int) -> list[Paper]: xml_text = http_get( ARXIV_API, { "search_query": search_query, "start": 0, "max_results": max_results, "sortBy": "submittedDate", "sortOrder": "descending", }, ) ``` ```python # scripts/doctor.py:178-188 params = { "search_query": "cat:cs.AI", "start": 0, "max_results": 1, "sortBy": "submittedDate", "sortOrder": "descending", } try: full_url = f"{ARXIV_API}?{urlencode(params)}" req = Request(full_url, headers={"User-Agent": "agent-daily-paper-doctor/1.0"}) with urlopen(req, timeout=20) as resp: text = resp.read().decode("utf-8", errors="replace") ``` ### Technical Analysis The arXiv API base URL uses HTTP instead of HTTPS. In normal digest and field-preparation opera ...[truncated 2716 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the plaintext API URL with an HTTPS endpoint supported by arXiv: ```python ARXIV_API = "https://export.arxiv.org/api/query" ``` 2. Reject redirects that downgrade an HTTPS request to HTTP. 3. After opening a response, verify that the final response URL still uses HTTPS. 4. Validate the expected response content type before parsing it as Atom XML. 5. Enforce a reasonable maximum response size to prevent memory exhaustion from malicious or erroneous responses. 6. Add stricter validation for arXiv identifiers, dates, categories, and generated URLs before persisting records. 7. Document that research fields and search terms are sent to arXiv, including the privacy implications. 8. Where confidentiality is important, allow users to route requests through an approved organizational proxy with appropriate transport security and logging controls. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (25)

Hidden Instructions

High
Category
Prompt Injection
Content
---
name: agent-daily-paper
description: 支持用户按一个或多个研究领域订阅 arXiv 最新论文,按重要性排序并以中英双语卡片形式推送(英文标题/中文标题/英文摘要/中文摘要/arXiv 链接)。支持每领域独立数量上限(5-20)、关键词高亮、NEW/UPDATED 版本标识、Markdown 存档,以及定时推送与即时推送双路径。首次使用时先完成订阅配置;领域可由 Agent 画像 JSON 自动补全英文名、关键词与会议列表。
---
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---
name: agent-daily-paper
description: 支持用户按一个或多个研究领域订阅 arXiv 最新论文,按重要性排序并以中英双语卡片形式推送(英文标题/中文标题/英文摘要/中文摘要/arXiv 链接)。支持每领域独立数量上限(5-20)、关键词高亮、NEW/UPDATED 版本标识、Markdown 存档,以及定时推送与即时推送双路径。首次使用时先完成订阅配置;领域可由 Agent 画像 JSON 自动补全英文名、关键词与会议列表。
---
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Ae1

High
Category
analysis-evasion
Content
这些规则属于 Agent 行为规范,维护在 `SKILL.md` 中,不应在 `run_digest.py` 里硬编码风格替换规则。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README recommends an OpenAI-based translation provider via OPENAI_API_KEY but does not clearly warn that paper titles, abstracts, or possibly extracted PDF text may be sent to an external third-party service. In a research workflow, this can expose unpublished, sensitive, or proprietary document content to an external provider without informed consent.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly describes scheduled execution, local file writes, and in the GitHub Actions path automatic commits of output and state, but it does not prominently warn users that installing or enabling the skill can create persistent local changes and, in remote setups, push updates back to a repository. In an agent-installation context, that omission can lead users to authorize automation without understanding that the skill may continuously modify files or generate repository activity over time.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The README says the agent 'must' use a fixed prompt framework for '中文结构化输出' and later requires '请使用...中文输出'. This is a natural-language locale constraint that forces a specific language rather than offering the user a choice, and no justification or opt-in is provided in the surrounding text.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The output specification requires the paper interpretation to be a Chinese long-form passage, and the later prompt template also mandates Chinese structured output. This is a language policy constraint presented as mandatory behavior, with no indication that the user can choose another language or opt in.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The single-paper interpretation section states the agent must use a fixed prompt framework and explicitly requires structured Chinese output, culminating in a requirement for at least 1000 Chinese characters. This is a natural-language locale restriction that applies regardless of user preference.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The setting "insight_lang": "zh" hard-codes a specific output language for this subscription. Under the policy, forcing a language or locale without user choice or a clearly documented region-specific justification is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This subscription likewise sets "insight_lang": "zh", which imposes a specific language choice in configuration. The file provides no indication of user choice, opt-in, or a justified locale restriction.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The configuration sets "insight_lang": "zh", which hard-codes the output language to Chinese. Under the policy rules, forcing a specific language without explicit user opt-in or a documented region-specific justification is a natural-language policy concern.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The natural-language string in the configuration is written only in Chinese, which imposes a specific language on users without any visible opt-in or alternative locale handling. This matches the policy category for language or locale constraints that are not optional or justified.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This manifest sets "insight_lang": "zh", which imposes a specific output language in configuration rather than offering a user-selectable locale. The file contains no nearby indication that the language is optional, user-chosen, or justified as a region-specific tool, so it appears to violate the language/locale policy.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The string assigned to setup_message is user-facing natural language and is written only in Chinese. For a cross-language bootstrap script, this forces a specific language without user opt-in, which matches the language/locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code file contains a natural-language status message in Chinese, while the rest of the script is otherwise English-oriented, and there is no indication that the skill is intentionally restricted to Chinese-speaking users. Under the policy rule, forcing a specific language without user opt-in or documented justification is a locale-policy violation.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
When `--use-openai-profile` is enabled, the script sends the user-supplied `field_name` to `https://api.openai.com/v1/responses`. This code path has no print/log statement, confirmation prompt, or inline warning near the transmission, so users running the script may not realize their input is being sent to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    req = Request(
        "https://api.openai.com/v1/responses",
        data=json.dumps(body).encode("utf-8"),
        headers={"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"},
        method="POST",
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
The CLI sets `--insight-lang` default to `zh`, which imposes a specific output language unless the user overrides it manually. This is a natural-language policy concern because the skill defaults to one language rather than obtaining user language preference or making the choice neutral by default.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code sends paper titles and abstracts to the OpenAI Responses API whenever the provider is set to openai/auto and credentials are present, but there is no in-code consent gate, disclosure, redaction step, or policy control over outbound data sharing. Even if arXiv metadata is often public, the finding is still valid because the skill transmits user-selected content to a third party and the surrounding config may include nonpublic or policy-sensitive material in other deployments.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    req = Request(
        "https://api.openai.com/v1/responses",
        data=json.dumps(body).encode("utf-8"),
        headers={"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"},
        method="POST",
Confidence
95% confidence
Finding
This is a concrete external transmission sink to api.openai.com carrying the translation payload and authorization header. In the context of this skill, the danger is not the HTTPS destination itself but that outbound sharing of paper content occurs without an explicit trust boundary control, user notice, or minimization of transmitted data.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
This helper transmits arbitrary English text to the OpenAI API for translation into Chinese, and that text can include extracted PDF content, summaries, or other assembled content beyond just public metadata. Because the function accepts free-form text and is used in the insight-generation pipeline, the privacy and data-governance risk is broader than the title/abstract case.

External Transmission

Medium
Category
Data Exfiltration
Content
],
    }
    req = Request(
        "https://api.openai.com/v1/responses",
        data=json.dumps(body).encode("utf-8"),
        headers={"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"},
        method="POST",
Confidence
98% confidence
Finding
This second external transmission sink sends arbitrary text for translation to OpenAI over the network. In this skill's context it is more sensitive because upstream callers may provide PDF-extracted or synthesized content, increasing the chance of sending larger or more sensitive text to a third party without explicit approval.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This JSON profile uses a Chinese field name as the primary identifier (`数据库优化器`) while the file provides no indication that users can choose their preferred language or locale. That can create a language/locale policy issue because the skill configuration implicitly privileges one language without documented opt-in or justification.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
`summarize_paper_insight` defaults `insight_lang` to `"zh"`, which imposes a specific output language absent any explicit opt-in at this point in the code. The policy allows locale constraints when user choice is explicit, but this default can cause forced language behavior.

Static analysis

No suspicious patterns detected.