Back to skill

Security audit

Nano Gpt

Security checks for vulnerabilities and agentic risk

Overview

This NanoGPT skill mostly matches its stated purpose, but it needs review because it can store and reveal an API token and can send that token plus user content to a configurable endpoint.

Review before installing. Prefer NANO_GPT_API_KEY over saving the token with config set, avoid running config get api-key in logged environments, keep NANO_GPT_BASE_URL set only to trusted HTTPS endpoints, and only provide prompts or media you intend to send to NanoGPT or the configured endpoint.

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
cli/src/config.ts:99
Finding

API Key Stored Without Enforced Owner-Only Permissions and Exposed by Configuration Command

Content
View full analysis
{ const configPath = getConfigPath(); const current = await readConfig(configPath); const next = { ...current, ...mapConfigValue(key, value) }; await mkdir(dirname(configPath), { recursive: true }); await writeFile(configPath, `${JSON.stringify(next, null, 2)}\n`, "utf8"); } ``` `cli/src/cli.ts:428-439`: ```ts configCommand .command("get") .argument("", `One of: ${CONFIG_KEYS.join(", ")}`) .action(async (key: string) => { assertConfigKey(key); const config = await readConfig(); const mapped = getConfigValue(config, key); if (mapped) { output.write(`${mapped}\n`); } }); ``` ### Technical Analysis The `config set api-key` operation stores the NanoGPT API key as plaintext JSON. Neither the configuration directory nor the file is created with an explicit owner-only mode. Consequently, effective permissions depend on the process umask and platform defaults. On systems with permissive settings, other local users or processes may be able to read the credential. The CLI also allows `nano-gpt config get api-key` to print the complete API key to standard output. This is inconsistent with `config list`, which applies `redactConfig`. Full disclosure increases the risk of leakage through terminal history capture, CI logs, process wrappers, support transcripts, or command output collected by automation. No privilege escalation is required beyond local read access to an insufficiently protected file or access to captured command output. ### Attack Path 1. A user runs `nano-gpt config set api-key `. 2. The CLI creates or overwrites `config.json` without explicitly enforcing mode ...[truncated 862 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
cli/src/config.ts:173
Finding

Configurable HTTP Endpoint Allows Cleartext Transmission of Bearer Tokens and User Content

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description promises a specific functional integration with the NanoGPT API for media generation workflows. However, the supplied code chunk only shows a generic command-line bootstrapper that delegates to createProgram() and handles errors. On its own, this code does not demonstrate the declared primary purpose or any of the advertised capabilities. Because the assessment is based on the supplied chunk only, the description is not accurately represented by the visible behavior here.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · cli/src/messages.ts (reported line 19)May include surrounding context.

ts
imageInputs: string[],
): Promise<MessageContent> {
  if (imageInputs.length === 0) {
    return prompt;
  }

  const parts: MessageContentPart[] = [];

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.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code persists the API key directly into a JSON config file under the user's home/config directory using default filesystem behavior and without setting restrictive permissions or steering users toward a safer secret store. If the config directory is backed up, synced, exposed to other local users, or read by other processes running as the same user, the NanoGPT token can be disclosed and then abused for unauthorized API usage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This reference file documents commands that transmit user-supplied text, images, videos, and configuration such as a base URL to an external model service, but it does not warn users that sensitive data may leave the local environment. In a skill specifically designed to use a third-party API and requiring an API token, the absence of privacy and data-handling guidance increases the risk of accidental disclosure of secrets, proprietary content, or regulated data.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · cli/package.json (reported line 21)May include surrounding context.

json
"node": ">=20"
  },
  "dependencies": {
    "commander": "^14.0.1"
  },
  "devDependencies": {
    "@types/node": "^24.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"commander": "^14.0.1"
  },
  "devDependencies": {
    "@types/node": "^24.0.0",
    "typescript": "^5.8.2"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
},
  "devDependencies": {
    "@types/node": "^24.0.0",
    "typescript": "^5.8.2"
  }
}

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI identifies itself as a "CLI for NanoGPT text and image APIs," but the code also exposes full video-generation and video-status commands elsewhere in the file. This is a manifest/documentation mismatch because the visible description understates the tool's actual scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This function performs an HTTP fetch of a user-supplied remote URL and reads the response body into memory, which is a network operation covered by the missing-user-warnings rule for code files. The code has no confirmation prompt, user-facing log/print, or inline comment/docstring disclosing that remote content will be fetched.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The function resolves an input path, checks access, and reads the local file contents, which is a safety-relevant file access operation under the rule. There is no confirmation prompt, user-facing log/print, or explanatory comment/docstring here indicating that the skill will read local image/video files from disk.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
cli/src/config.ts:64

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
cli/test/config.test.ts:40