Back to skill

Security audit

Oganim Deploy

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed deployment runbook, but it gives agents broad production credentials and includes unsafe production account-testing workflows.

Install only if this is your own project and you intend to let the agent operate production deployment, database, CRM, and Supabase admin workflows. Prefer staging data, pinned dependencies, isolated execution without broad secret-file access, explicit approval before production changes, and remove the customer-password mutation recipe before use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/playwright-recipes.md:130
Finding

Production customer passwords can be destructively overwritten during testing

Content
View full analysis
l.includes('=')) .map(l => { const i = l.indexOf('='); return [l.slice(0, i), l.slice(i + 1)]; }) ); const USER_ID = '...'; const TEMP_PASS = 'temp-' + Date.now(); await fetch(`${cred.SUPABASE_URL}/auth/v1/admin/users/${USER_ID}`, { method: 'PUT', headers: { apikey: cred.SUPABASE_SERVICE_ROLE_KEY, Authorization: 'Bearer ' + cred.SUPABASE_SERVICE_ROLE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ password: TEMP_PASS }), }); // ... do test work ... // IMPORTANT: scramble the password back so the test password isn't usable. await fetch(`${cred.SUPABASE_URL}/auth/v1/admin/users/${USER_ID}`, { method: 'PUT', headers: { apikey: cred.SUPABASE_SERVICE_ROLE_KEY, Authorization: 'Bearer ' + cred.SUPABASE_SERVICE_ROLE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ password: 'reset-' + Math.random().toString(36) }), }); ``` ### Technical Analysis The recipe uses the production Supabase service-role key to replace the password of an arbitrary user identified by `USER_ID`. A service-role key bypasses normal row-level authorization and can administer the entire Supabase project. The purported cleanup does not restore the original password. It changes the password to another unknown value, permanently invalidating the customer's original credentials. In addition, the initial temporary password is based only on the current timestamp and is not cryptographically random. If execution terminates before the second request, that predictable password can remain active. Mutating a real customer's cr ...[truncated 1172 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/playwright-recipes.md:26
Finding

Routine deployment and verification workflows consume excessively privileged production credentials

Content
View full analysis
l.includes('=')) .map(l => { const i = l.indexOf('='); return [l.slice(0, i), l.slice(i + 1)]; }) ); const gen = await fetch(`${cred.SUPABASE_URL}/auth/v1/admin/generate_link`, { method: 'POST', headers: { apikey: cred.SUPABASE_SERVICE_ROLE_KEY, Authorization: 'Bearer ' + cred.SUPABASE_SERVICE_ROLE_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'magiclink', email }), }).then(r => r.json()); ``` ```js const PASS = fs.readFileSync(process.env.HOME + '/.openclaw/credentials/supabase/admin_password.txt', 'utf8').trim(); ``` ### Technical Analysis The Skill's normal workflow combines several highly privileged production capabilities: - A Vercel token capable of production deployment - PostgreSQL superuser credentials used for migrations - A Supabase service-role key that ...[truncated 1786 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/setup-playwright.sh:14
Finding

Unpinned npm packages are downloaded and executed in a credential-bearing environment

Content
View full analysis
&1 | tail -3 fi ``` The deployment workflow also invokes an unpinned CLI: ```bash VERCEL_TOKEN=$(cat ~/.openclaw/credentials/vercel/token) \ npx vercel deploy --prod --yes ``` The documented setup repeats the unpinned installation: ```bash mkdir -p /tmp/-test && cd /tmp/-test npm init -y >/dev/null && npm i playwright --no-save ``` ### Technical Analysis Neither `playwright` nor the Vercel CLI is pinned to a reviewed version. The Skill does not include a lockfile or integrity metadata for the temporary npm project. As a result, npm resolves mutable package and transitive dependency versions at execution time. `npx vercel` may download and execute the current registry version directly. npm packages and their dependencies can execute lifecycle scripts during installation. Such code inherits the filesystem and environment permissions of the invoking user, which is particularly dangerous because the documented workflow has access to production Vercel and Supabase credentials. No malicious npm package is embedded in the reviewed project. The vulnerability is the uncontrolled supply-chain execution path. ### Attack Path 1. An attacker compromises an npm publisher account, a transitive dependency, or the package-distribution path. 2. The operator runs `npm i playwright --no-save` or `npx vercel deploy`. 3. npm resolves and downloads a version that was not reviewed with this Skill. 4. Package installation code or the downloaded CLI executes with the operator's per ...[truncated 544 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/playwright-recipes.md:45
Finding

Authenticated production probes disable TLS validation and Chromium sandboxing

Content
View full analysis
console.log('[PAGEERROR]', e.message)); await page.goto(url, { waitUntil: 'networkidle' }); ``` The same security bypasses are used in other recipes: ```js const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] }); const page = await (await browser.newContext({ viewport: { width: 412, height: 915 }, ignoreHTTPSErrors: true, })).newPage(); ``` ```js const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] }); const page = await (await browser.newContext({ ignoreHTTPSErrors: true })).newPage(); ``` ### Technical Analysis `--no-sandbox` disables an important Chromium process-containment boundary. If a visited page exploits a browser vulnerability, the resulting process has a greater ability to affect the host. `ignoreHTTPSErrors: true` causes the browser to accept expired, mismatched, self-signed, or otherwise invalid certificates. This weakens assurance that credentials, magic-link tokens, and authenticated sessions are being sent to the intended production server. These options are unnecessary for a correctly configured public HTTPS production deployment. Their combined use is particularly risky because the recipes process real authentication tokens and administrative credentials. ### Attack Path 1. An attacker compromises the target website, DNS path, proxy, or network connection. 2. The probe accepts an invalid TLS certificate instead of terminating the connection. 3. The probe sends authentication material or loads attacker-controlled ...[truncated 592 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/playwright-recipes.md:53
Finding

Magic-link URLs and authenticated customer content may be retained in logs and shared workspace artifacts

Content
View full analysis
false); console.log('login form visible (= auth FAILED):', stillOnLogin); console.log('current URL:', page.url()); console.log('body excerpt:', (await page.locator('body').innerText()).slice(0, 300)); await page.screenshot({ path: '/tmp/oganim-test/magic-link.png' }); await browser.close(); ``` The Skill then recommends moving screenshots into an Agent-readable workspace: ```bash cp /tmp/oganim-test/foo.png ~/.openclaw/workspace/foo.png # Then: tool call → image(path=~/.openclaw/workspace/foo.png, prompt="...") ``` ```text `/tmp/oganim-test/` is outside the assistant's read boundary, so screenshots must live somewhere under `~/.openclaw/workspace/` to be inspected. ``` ### Technical Analysis The magic-link recipe prints the complete current URL after visiting a URL containing `token_hash`. Depending on application redirect behavior, that sensitive token may remain in the URL and be written to terminal or CI logs. The recipe also logs the first 300 characters of the authenticated page and takes an unrestricted screenshot. These outputs may contain customer names, account information, financial details, or other portal content. The instructions explicitly copy screenshots from a temporary test directory into an Agent-readable workspace, but do not prescribe redaction, restrictive permissions, retention limits, or deletion. ### Attack Path 1. The probe generates a real customer's magic-link token using the service-role key. 2. It opens the authenticated production portal. 3. The current URL, potentially including the authentication token ...[truncated 765 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill explicitly directs the agent to use a local file containing Supabase credentials to connect as the postgres superuser for migrations. Even though this may be operationally legitimate, exposing a path to high-value secrets and normalizing superuser access materially increases the risk of credential misuse, accidental disclosure, or destructive database actions if the skill is invoked in the wrong context.

Content

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

node deploy/run-migration.cjs deploy/migration-stageN-.sql

text

The runner connects to the Supabase pooler as the `postgres` superuser using credentials from `~/.openclaw/credentials/supabase/credentials.env`.

**Always include `reset role;`** at the top of any migration that creates triggers, alters tables, or replaces policies — otherwise the pooler may leave the session as `authenticated` from a previous transaction and ownership checks fail. See [references/migration-template.sql](references/migration-template.sql).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Then write a probe (see [references/playwright-recipes.md](references/playwright-recipes.md) for templates) that:

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The skill enumerates a concrete credential file path and names sensitive values including the anon key, service role key, and DB password. This materially aids secret discovery and increases the chance that an automated agent, log pipeline, or downstream tool will access or expose credentials during execution.

Content

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

md
## Project Secrets Reference

- `~/.openclaw/credentials/vercel/token` (chmod 600)
- `~/.openclaw/credentials/supabase/credentials.env` — `SUPABASE_URL`, `SUPABASE_PROJECT_REF`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `SUPABASE_DB_PASSWORD`
- `~/.openclaw/credentials/supabase/admin_password.txt` — your CRM admin password. Treat as production credential.

## See Also

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill reveals the existence and path of a production admin password file for the CRM. In an agentic environment, this creates a strong temptation and clear roadmap for credential access; compromise of this password could expose sensitive admin functionality and customer data.

Content

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

md
- `~/.openclaw/credentials/vercel/token` (chmod 600)
- `~/.openclaw/credentials/supabase/credentials.env` — `SUPABASE_URL`, `SUPABASE_PROJECT_REF`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `SUPABASE_DB_PASSWORD`
- `~/.openclaw/credentials/supabase/admin_password.txt` — your CRM admin password. Treat as production credential.

## See Also

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This recipe reads a Supabase credentials file containing a service-role key and then uses it to call admin auth APIs that generate real magic links. Service-role credentials are highly privileged secrets; embedding instructions to access them from a general verification recipe meaningfully increases the chance of credential misuse, leakage, or privilege abuse.

Content

Scanner excerpt · references/playwright-recipes.md (reported line 28)May include surrounding context.

md
const fs = require('fs');
const { chromium } = require('playwright');
const cred = Object.fromEntries(
  fs.readFileSync(process.env.HOME + '/.openclaw/credentials/supabase/credentials.env', 'utf8')
    .split('\n').filter(l => l.includes('='))
    .map(l => { const i = l.indexOf('='); return [l.slice(0, i), l.slice(i + 1)]; })
);

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The recipe reads an admin password from disk and automates interactive login to the CRM. Storing and using a reusable admin password in this way expands the attack surface for credential theft and enables full administrative access if the secret is exposed through logs, prompts, screenshots, or local compromise.

Content

Scanner excerpt · references/playwright-recipes.md (reported line 105)May include surrounding context.

js
const fs = require('fs');
const { chromium } = require('playwright');
const PASS = fs.readFileSync(process.env.HOME + '/.openclaw/credentials/supabase/admin_password.txt', 'utf8').trim();

(async () => {
  const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This recipe again reads the Supabase service-role credentials and uses them to modify customer account passwords via admin APIs. That is highly sensitive because it grants direct control over user authentication state and could lock out users, impersonate them, or permanently weaken account security if mishandled.

Content

Scanner excerpt · references/playwright-recipes.md (reported line 134)May include surrounding context.

js
const cred = Object.fromEntries(
  fs.readFileSync(process.env.HOME + '/.openclaw/credentials/supabase/credentials.env', 'utf8')
    .split('\n').filter(l => l.includes('='))
    .map(l => { const i = l.indexOf('='); return [l.slice(0, i), l.slice(i + 1)]; })
);

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

The skill instructs use of npx vercel deploy --prod without pinning a specific Vercel CLI version. This can cause execution of an unexpected or newly published package version, creating supply-chain risk and reducing deployment reproducibility for a production workflow.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

When you can't easily reproduce a UI bug, run a Playwright probe. They expect pg and playwright installed under /tmp/<project>-test/:

bash
mkdir -p /tmp/<project>-test && cd /tmp/<project>-test
npm init -y >/dev/null && npm i playwright --no-save
# If your cached chromium version doesn't match the Playwright npm version:
ln -sfn ~/.cache/ms-playwright/chromium_headless_shell-1217 \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
## Project Secrets Reference

- `~/.openclaw/credentials/vercel/token` (chmod 600)
- `~/.openclaw/credentials/supabase/credentials.env` — `SUPABASE_URL`, `SUPABASE_PROJECT_REF`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `SUPABASE_DB_PASSWORD`
- `~/.openclaw/credentials/supabase/admin_password.txt` — your CRM admin password. Treat as production credential.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/playwright-recipes.md (reported line 8)May include surrounding context.

Setup (once per server)

bash
mkdir -p /tmp/oganim-test && cd /tmp/oganim-test
npm init -y >/dev/null && npm i playwright --no-save

# Playwright pins a browser version; symlink existing cache so the install

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The recipe explicitly instructs copying screenshots from browser-based verification runs into an assistant-readable workspace, and those screenshots may contain authenticated CRM or customer-portal content. That creates a real confidentiality risk because session-visible PII, admin views, or customer data can be exposed to broader tooling without a clear minimization or redaction requirement.

Content

No source excerpt is available for this finding.