Back to skill

Security audit

Peer Reviewer

Security checks for vulnerabilities and agentic risk

Overview

The skill performs its stated peer-review function, but it includes unsafe shell execution and under-scoped handling of sensitive paper content and credentials.

Install only if you are comfortable sending paper text and extracted claims to configured third-party LLM/search providers. Avoid using it on confidential or unpublished manuscripts unless you first fix or disable the shell-based SkillSearchAdapter, switch arXiv to HTTPS, restrict credentials to least privilege, and harden report storage paths.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/adapters/skill_search.ts:15
Finding

Shell Command Injection Through Paper-Derived Claims

Content
View full analysis
0) { console.warn("SkillSearchAdapter stderr:", stderr); } ``` The vulnerable `claim` originates from paper content and is passed to this adapter by `DevilsAdvocateAgent` in `src/agents.ts:20-30`. ### Technical Analysis The adapter constructs a shell command by interpolating a paper-derived claim into a string passed to Node.js `child_process.exec()`. Because `exec()` invokes a command shell, shell metacharacters and command-substitution expressions in the claim may be interpreted by that shell. Replacing double quotes with `\"` is not sufficient shell escaping. For example, command substitutions using `$(...)` or backticks can still be evaluated inside double-quoted shell arguments. The deconstruction prompt instructs the LLM to quote rather than paraphrase source content, so malicious syntax embedded in a paper may be preserved in the generated claim. Although LLM transformation makes exact preservation nondeterministic, the adapter must treat all claim values as untrusted. ### Attack Path 1. An attacker supplies a paper or raw claim containing shell substitution syntax such as `$(command)`. 2. `DeconstructionAgent` sends the document to the LLM and obtains a logic graph containing the malicious text as a claim. 3. `DevilsAdvocateAgent.attack()` passes the claim to `SkillSearchAdapter.findContradictions()`. 4. `SkillSearchAdapter` interpolates the claim into a shell command. 5. `exec()` launches a shell, which can evaluate the injected substitution. 6. The injected command executes with the privileges of the Node.js process. In standalone mode, this path is selected wh ...[truncated 599 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/adapters/file_storage.ts:20
Finding

Path Traversal in Report Storage Identifiers

Content
View full analysis
(collection: string, id: string, data: T): Promise { const collectionDir = path.join(this.baseDir, collection); await fs.mkdir(collectionDir, { recursive: true }); const filePath = path.join(collectionDir, `${id}.json`); await fs.writeFile(filePath, JSON.stringify(data, null, 2)); } ``` The public entry point accepts a caller-controlled identifier in `src/index.ts:39-43`: ```typescript async saveReport(report: MeritReport, id?: string): Promise { const reportId = id || `report-${Date.now()}`; await this.storage.save('reports', reportId, report); return reportId; } ``` ### Technical Analysis The public `saveReport()` method allows the caller to provide an arbitrary report identifier. `FileStorageAdapter.save()` appends `.json` and passes the result to `path.join()` without rejecting path separators or checking whether the resolved path remains under the intended collection directory. An identifier containing traversal components such as `../` can therefore escape `data/reports`. `path.join()` normalizes traversal components but does not enforce directory containment. The related `get()` method constructs paths in the same unsafe manner and may read JSON files outside the intended collection when exposed to untrusted `collection` or `id` values. ### Attack Path 1. An application exposes or otherwise passes an untrusted identifier to `PeerReviewer.saveReport()`. 2. The attacker submits an identifier such as `../../target`. 3. The adapter constructs a path equivalent to `data/reports/../../target.json`. 4. Path normalization resolves the destination outside the reports directory. 5. The report JSON is written to the escaped path if the process has filesystem permission. ### Impact Assessment An attack ...[truncated 434 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/adapters/arxiv.ts:8
Finding

Paper-Derived ArXiv Queries Transmitted Over Plaintext HTTP

Content
View full analysis
w.length > 4).join(' AND '); const query = `all:${encodeURIComponent(keywords)}`; const response = await axios.get(`http://export.arxiv.org/api/query?search_query=${query}&start=0&max_results=5`); const result = await parseStringPromise(response.data); ``` ### Technical Analysis The adapter uses an unencrypted `http://` endpoint. The query is derived from claims extracted from the reviewed paper, so confidential or unpublished research terms can be exposed to network observers. Because HTTP provides no authenticated transport integrity, a network-positioned attacker can also alter the XML response. Returned titles and summaries are incorporated into the context sent to the Devil’s Advocate LLM, allowing manipulated search results to affect the final review. This network request supports the declared literature-search functionality, but plaintext transport is not the minimum safe privilege or disclosure mechanism when HTTPS is available. ### Attack Path 1. A user reviews a confidential or unpublished paper. 2. Claims extracted by the LLM are converted into ArXiv search keywords. 3. The adapter transmits those keywords using plaintext HTTP. 4. A network observer reads the query and learns portions of the paper’s claims. 5. A man-in-the-middle attacker may modify the ArXiv XML response. 6. The modified titles or summaries are incorporated into downstream LLM context and may influence objections and scoring. ### Impact Assessment The confidentiality impact includes disclosure of paper-derived keywords and research claims to parties capable of observing network traffic. The integrity impact includes manipulation of liter ...[truncated 204 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
src/adapters/openclaw_llm.ts:64
Finding

Gemini API Key May Be Disclosed Through URL-Based Authentication and Error Logging

Content
View full analysis
(systemPrompt: string, userContent: string, schema: z.ZodType): Promise { // Basic implementation for Gemini API via REST const model = process.env.GEMINI_MODEL || 'gemini-1.5-pro'; const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${this.geminiKey}`; try { const response = await axios.post(url, { contents: [{ parts: [{ text: systemPrompt + "\n\nOutput strictly JSON.\n\n" + userContent }] }], generationConfig: { responseMimeType: "application/json" } }); const text = response.data.candidates[0].content.parts[0].text; return schema.parse(JSON.parse(text)); } catch (error) { console.error("Gemini API call failed:", error); throw error; } } ``` ### Technical Analysis The Gemini API key is embedded in the request URL as a query parameter. Although the request uses HTTPS, URLs are commonly retained in client diagnostics, proxy logs, monitoring systems, and error objects. When Axios throws an error, the error can include request configuration containing the complete URL. Passing the entire error object to `console.error()` may therefore disclose the API key to application logs. The same unsanitized error is rethrown and may be logged again by upstream code. ### Attack Path 1. The Skill is configured with `GEMINI_API_KEY` or `GOOGLE_API_KEY`. 2. A Gemini request fails because of a network, authentication, quota, or API error. 3. Axios creates an error object containing request metadata, potentially including the URL. 4. The adapter logs the complete error object. 5. An operator, log aggregation service, or user with log access obtains the API key from the record ...[truncated 342 chars]
Remediation
View remediation
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 (34)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · README.md (reported line 11)May include surrounding context.

md
The system uses three specialized AI agents:

1.  **The Deconstructor:** Parses raw text into a formal Logic Graph (Toulmin Model), extracting claims, premises, and evidence without judgment.
2.  **The Devil's Advocate:** Takes the claims and actively searches for contradictions (using Google Serper & ArXiv). It looks for theoretical conflicts, empirical contradictions, and prior art.
3.  **The Judge:** Evaluates the Logic Graph against the Devil's Advocate's objections. It scores the paper on logical coherence, foundational integrity, and empirical falsifiability.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill documentation presents a reviewer tool, but the analyzed behavior includes reading local credential files, using Google authentication, and making outbound requests to Vertex AI. This hidden credential and network dependency raises the risk of secret exposure, unauthorized billing, and silent export of sensitive manuscript data to external services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill documentation presents a reviewer tool, but the analyzed behavior includes reading local credential files, using Google authentication, and making outbound requests to Vertex AI. This hidden credential and network dependency raises the risk of secret exposure, unauthorized billing, and silent export of sensitive manuscript data to external services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill documentation presents a reviewer tool, but the analyzed behavior includes reading local credential files, using Google authentication, and making outbound requests to Vertex AI. This hidden credential and network dependency raises the risk of secret exposure, unauthorized billing, and silent export of sensitive manuscript data to external services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill documentation presents a reviewer tool, but the analyzed behavior includes reading local credential files, using Google authentication, and making outbound requests to Vertex AI. This hidden credential and network dependency raises the risk of secret exposure, unauthorized billing, and silent export of sensitive manuscript data to external services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill documentation presents a reviewer tool, but the analyzed behavior includes reading local credential files, using Google authentication, and making outbound requests to Vertex AI. This hidden credential and network dependency raises the risk of secret exposure, unauthorized billing, and silent export of sensitive manuscript data to external services.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/adapters/vertex_ai.ts (reported line 80)May include surrounding context.

ts
}

  /**
   * Get access token for Vertex AI API calls
   */
  private async getAccessToken(): Promise<string> {
    const client = await this.auth.getClient();

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/adapters/vertex_ai.ts (reported line 86)May include surrounding context.

ts
}

  /**
   * Get access token for Vertex AI API calls
   */
  private async getAccessToken(): Promise<string> {
    const client = await this.auth.getClient();

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README states that the skill searches external services and auto-detects providers, but it does not warn users that paper contents or derived claims may be sent to third-party APIs and that locally available credentials may be used automatically. In a research-review context, this can expose unpublished manuscripts, confidential data, or proprietary research to remote services without informed user consent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises executable CLI usage and references environment-based credentials, but declares no tool scope or permissions. That creates an authorization gap where users or orchestrators may treat the skill as documentation-only while it actually implies access to environment secrets and code execution capabilities.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The adapter sends user-provided claim content to arXiv's external API without any evidence in this file of user notice, consent, or data minimization. In an academic review skill, claims may contain unpublished ideas, proprietary research, or sensitive manuscript text, so transmitting them to a third party can create confidentiality and privacy risks even if the destination is legitimate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The adapter sends systemPrompt and userContent to OpenAI over HTTP, which may include user or system data. Although the code logs failures, there is no confirmation prompt or user-facing notice in this file that content will be transmitted to a third-party service.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · src/adapters/openclaw_llm.ts (reported line 39)May include surrounding context.

ts
private async callOpenAI<T>(systemPrompt: string, userContent: string, schema: z.ZodType<T>): Promise<T> {
    try {
      const response = await axios.post(
        'https://api.openai.com/v1/chat/completions',
        {
          model: process.env.OPENAI_MODEL || 'gpt-4o',
          messages: [

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The Gemini implementation sends combined systemPrompt and userContent to Google's API, which can expose user or system data to a third party. This file contains error logging but no user-facing warning, confirmation, or explanatory comment disclosing that data is transmitted externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The adapter sends the raw user-provided claim to a third-party search provider without any evidence of user notice, consent, or data minimization. In an academic peer-review context, claims may contain unpublished research ideas, proprietary data, or sensitive text, so transmitting them externally can leak confidential information and create privacy or intellectual-property risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This adapter builds a shell command with untrusted input (claim) and executes it via child_process.exec, which invokes a shell. Escaping only double quotes is insufficient to prevent shell metacharacter injection, and the executable path itself is also injectable if attacker-controlled. In the context of an academic reviewer skill, external CLI execution is not essential to the stated purpose and expands the attack surface significantly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The review flow forwards paper text into an engine backed by LLM and search adapters, but the call site provides no explicit warning or consent mechanism before transmitting potentially sensitive manuscript content to third-party providers. For an academic peer-review skill, this context makes the issue more serious because papers may be unpublished, embargoed, or contain proprietary research.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The CLI conditionally enables external search providers, which can send paper-derived claims or queries to third-party services without an explicit consent prompt at execution time. In an academic review context, this is risky because unpublished or confidential manuscript content may be indirectly disclosed to external services during contradiction checking.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code executes a separate Node-based tool via SkillSearchAdapter based on the presence of a relative-path script, creating a supply-chain and arbitrary code execution risk if that adjacent tool is replaced or tampered with. Because the execution target is discovered dynamically from the filesystem rather than being strongly pinned or verified, a local attacker or compromised dependency tree could cause unintended code to run.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation instructs users to provide cloud credentials but gives no warning about protecting authentication material or limiting privileges. In the context of a paper-review skill, this can lead users to place sensitive service-account files in the project root without understanding the exposure and misuse risks.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a caret range (^1.6.0), which allows installation of newer semver-compatible releases without an explicit review. This creates supply-chain uncertainty and makes builds non-reproducible, especially concerning here because axios is network-facing and has had multiple advisories, so different environments could resolve to different risk profiles.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"author": "Sebastian Schepis",
  "license": "MIT",
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.4.0",
    "google-auth-library": "^9.6.0",
    "xml2js": "^0.6.0",

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dotenv dependency is not pinned to an exact version, allowing drift across installations. While dotenv is not inherently dangerous by itself, unpinned dependencies increase supply-chain risk and reduce reproducibility of the skill build.

Content

Scanner excerpt · package.json (reported line 24)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.4.0",
    "google-auth-library": "^9.6.0",
    "xml2js": "^0.6.0",
    "zod": "^3.22.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

google-auth-library is specified with a version range rather than an exact version, so deployed instances may install different code over time. Because this library handles authentication flows and credentials, unexpected updates can have security-sensitive effects if a bad or vulnerable release is pulled in.

Content

Scanner excerpt · package.json (reported line 25)May include surrounding context.

json
"dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.4.0",
    "google-auth-library": "^9.6.0",
    "xml2js": "^0.6.0",
    "zod": "^3.22.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

xml2js is unpinned, which is a supply-chain hygiene weakness, and this is more relevant because XML parsers have historically had security issues including prototype pollution. The skill context may involve ingesting untrusted academic content or metadata, so parser version drift can change exposure across environments.

Content

Scanner excerpt · package.json (reported line 26)May include surrounding context.

json
"axios": "^1.6.0",
    "dotenv": "^16.4.0",
    "google-auth-library": "^9.6.0",
    "xml2js": "^0.6.0",
    "zod": "^3.22.0"
  },
  "devDependencies": {

Static analysis

Detected: suspicious.env_credential_access, suspicious.potential_exfiltration

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/adapters/openclaw_llm.ts:17

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/adapters/vertex_ai.ts:47

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
src/adapters/vertex_ai.ts:52