Back to skill

Security audit

PowPow Registration — sign up Bubble, pin travel diary for map, talk with digital pesin

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to match its registration and payment purpose, but it stores session/payment state in a predictable temporary file and can open local payment pages, so it needs careful review before use.

Install only if you are comfortable with an agent creating a PowPow account, sending your email and registration details to the official PowPow service, temporarily storing a login token on this machine, and opening a browser payment page when you choose to subscribe. Avoid using it on shared machines, require confirmation before any payment page is opened, and run the cleanup command after the flow finishes.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/powpow-register.mjs:40
Finding

Predictable temporary state file permits session-token disclosure and workflow-state manipulation

Content
View full analysis

Vulnerability Details

File Location: scripts/powpow-register.mjs, lines 40–55 and 203–210
Vulnerability Type: Insecure predictable temporary file
Risk Level: Medium

Vulnerable Code

js
const STATE_FILE = join(tmpdir(), 'powpow-register-state.json');

function loadState() {
  try {
    return JSON.parse(readFileSync(STATE_FILE, 'utf8'));
  } catch {
    return {};
  }
}

function saveState(patch) {
  const s = { ...loadState(), ...patch };
  writeFileSync(STATE_FILE, JSON.stringify(s, null, 2), { mode: 0o600 });
  return s;
}

The sensitive session token is subsequently stored in this file:

js
const token = r.cookies['powpow_token'] || '';
if (!token) die('Registration succeeded, but no session cookie was captured');
saveState({
  username: r.data?.user?.username || username,
  nickname: r.data?.user?.nickname || nickname,
  userId: r.data?.userId,
  token,
  step: 'registered-pending',
  registeredAt: new Date().toISOString(),
});

Technical Analysis

The state path is a fixed, globally predictable name under the system temporary directory. On a shared operating system, another local user can create this path before the victim invokes the Skill.

The { mode: 0o600 } option only determines permissions when Node.js creates a new file. It does not securely replace an existing file, correct an existing file's permissions, reject symbolic links, or verify ownership. Consequently, writeFileSync() can write sensitive state into a pre-created attacker-readable file or follow a symbolic link.

The file contains a bearer JWT captured from the registration response. The token is later accepted by the platform's one-click-login bridge and authenticated API requests. The same file also controls workflow fields such as the username, provider, order number, and current session token. loadState() trusts this pre-existing content without validating file type, ow ...[truncated 1824 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a private per-user or per-session directory under the temporary directory with mode 0700.
  2. Use an unpredictable per-session filename instead of a global fixed name.
  3. Atomically create the state file with exclusive-create and no-follow semantics, such as O_CREAT | O_EXCL | O_NOFOLLOW, with mode 0600.
  4. Before every read or update, use lstat() and verify that the path is a regular file, is owned by the current effective user, has no unexpected hard links, and has restrictive permissions.
  5. Do not perform read-modify-write operations through a path that may have been replaced between checks. Use an already-opened, validated file descriptor where possible.
  6. Write updates to a securely created file in the private directory and atomically rename it within that same protected directory.
  7. Keep the bearer token only in process-local protected state where workflow architecture permits, and minimize its lifetime.
  8. Generate separate state namespaces for concurrent registrations so one invocation cannot overwrite or consume another invocation's account state.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (24)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Main script `scripts/powpow-register.mjs`: **zero dependency**, e need **Node >= 18**. Before you start, run `node scripts/powpow-register.mjs status` one tim

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to invoke OS-level commands (start, open, xdg-open) to launch a local payment page automatically, without requiring an explicit user confirmation immediately before execution. Triggering local applications or browser actions from a chat-driven workflow expands the agent's authority from guidance into device control and can surprise the user or be abused if file paths or invocation context are compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions at L147-L149 require the agent to continue in a specific PowPow service-style tone written in Nigerian Pidgin-like phrasing. This is a language/locale constraint imposed by the skill, and there is no opt-in, fallback, or user language selection described.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest sets the skill language to "pcm" only, and there is no nearby indication that users can opt into another language or that the restriction is required for a region-specific purpose. This may violate language/locale policy when the skill forces a single language without user choice.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The listing notes describe broad agent-driven actions such as sending verification codes, registering accounts, placing orders, and conditionally routing users into payment flows, but they do not clearly define when the skill activates or what explicit user consent boundaries apply. In a skill that can automate registration and ordering, unclear invocation scope increases the risk of unintended high-impact actions, surprise transactions, or phishing-like social engineering behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document consistently instructs the agent in a specific language style rather than offering localization based on user preference. Under the stated policy, forcing a specific language or locale without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly says it writes paymentHtml to a temporary local HTML file and opens it via a system command, but it does not present a clear user-facing warning about this behavior or its local-execution implications. Opening generated HTML through system commands increases the attack surface for unsafe file handling, command invocation mistakes, or unexpected browser execution paths, especially in a payment flow where users may assume everything stays inside the web app.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Line L25 embeds a Chinese-only error string as the expected login behavior, and similar Chinese-only strings appear throughout the troubleshooting table. The file does not indicate that users can choose their preferred language or that the locale restriction is required for a region-specific workflow, which makes this a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The instruction says to send screenshots whenever the user has no idea about Bubble or needs to 'see' the finished product, but it does not define clear trigger boundaries or exclusions. This is ambiguous enough to overlap with common conversational requests for explanation or examples, increasing the chance of unintended invocation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The header comment asserts that only a minimal set of fields are written to the temporary state file, but the implementation stores additional sensitive and privacy-relevant data such as userId, payment metadata, subscription IDs, approval URLs, and timestamps. This mismatch can lead operators or downstream tooling to underestimate what is retained on disk, increasing the risk of unintended disclosure from temp-directory inspection, backups, crash collection, or multi-user host access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

This markdown file describes behavior that affects user workflow and system state by opening a payment page via start/open/xdg-open. While the payment purpose is explained, there is no explicit warning at the step itself that the command will launch the user's browser or local payment page and take them out of the chat flow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The documented flow requires bearer-authenticated calls to payment and subscription endpoints, which means account authentication data is transmitted during the process, but the skill does not clearly warn the user about that data handling. While such transmission may be operationally necessary, failing to disclose it can mislead users about what credentials or session artifacts are being used during a sensitive payment workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The quick-find table maps broad conversational situations like 'Opening intro' or 'after registration wetin I fit do?' directly to screenshots, but it does not clarify when not to send images or whether user consent is needed. This broad mapping can cause the skill to send screenshots in routine discussion without a sufficiently specific activation boundary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script writes an HTML page with lang="en" and English-only title text for the PayPal redirect flow. This is a natural-language locale choice embedded in the skill without offering the user a language option or documenting why English is required.

Content

No source excerpt is available for this finding.