Back to skill

Security audit

Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its OKKI Go prospecting purpose, but it includes high-impact install, credential, email-send, endpoint-override, and persistent notification behaviors that need review before installation.

Install only if you trust OKKI Go and the @okki-global npm publisher. Keep OKKIGO_BASE_URL unset unless you are deliberately using a trusted test endpoint, confirm recipients and final email content before any send, and decline update notifications if you do not want a recurring cron job. Expect the skill to store an API key, profile data, viewed/unlocked state, and attribution metadata locally under the OKKI Go config directory.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/okki-api.js:11
Finding

Unvalidated API Base URL Can Exfiltrate API Keys and Sensitive Business Data

Content
View full analysis
= 300) { const error = new Error(formatApiError(response.statusCode, body)); error.statusCode = response.statusCode; error.body = body; throw error; } return { statusCode: response.statusCode, body }; } function request(method, urlString, headers, payload) { return new Promise((resolve, reject) => { const url = new URL(urlString); const transport = url.protocol === 'http:' ? http : https; const body = payload === undefined ? null : JSON.stringify(payload); const requestHeaders = Object.assign({}, headers); if (body !== null) { requestHeaders['Content-Length'] = Buffer.byteLength(body); } const req = transport.request({ method, hostname: url.hostname, port: url.port || (url.protocol === 'http:' ? 80 : 443), path: `${url.pathname}${url.search}`, headers: requestHeaders }, (res) => { ``` ### Technical Analysis `OKKIGO_BASE_URL` is accepted without validating its protocol, hostname, port, or origin. The code then attaches the resolved API key through the `Authorization: ApiKey ...` header and sends the request to the resulting URL. The implementation explicitly permits both HTTP and HTTPS. Consequently, an inherited or manipulated environment variable can redirect authenticated requests to an arbitrary host or expose them in plainte ...[truncated 1786 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send-email.js:111
Finding

Email Send Wrapper Does Not Enforce Recipient and Content Confirmation

Content
View full analysis
' --compact ``` 3. `validatePayload()` verifies only the array's presence and size. 4. `postJson()` immediate ...[truncated 902 chars]
Remediation
View remediation

other

Warning
Location
scripts/lib/runtime-attribution.js:82
Finding

Persistent Installation and Agent Attribution Is Sent Without Runtime Opt-Out Enforcement

Content
View full analysis
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
references/authentication.md:39
Finding

Agent-Led Installer Executes an Unpinned Remote Package Using npx

Content
View full analysis
``` Then execute the installer. If the host requires command approval, request approval using the host's normal mechanism. If the host has no command execution capability, or the user refuses execution approval, explain that installation cannot be completed from this agent surface and provide the exact command as a fallback. ``` ### Technical Analysis The skill explicitly instructs the agent to retrieve and execute `@okki-global/okki-go@latest` using `npx -y`. The `@latest` tag is mutable, so the code executed during installation is not the code reviewed in this artifact. The `-y` option also suppresses the normal package installation prompt. If the package publisher account, npm registry path, release process, or latest release is compromised, future installations can execute changed code with the permissions of the agent process. Depending on the selected install target, the installer may write to global configuration, multiple agent runtimes, or a custom path. This is a supply-chain and remote-payload risk even though the package name is scoped and not an obvious typosquat. The key issue is that the effective payload can change after audit without a corresponding review of this skill artifact. ### Attack Path 1. An attacker compromises the npm publisher account, release pipeline, package contents, or mutable `latest` distribution tag. 2. A malicious package version is published as `@okki-global/okki-go@latest`. 3. A user asks the agent to install or update OKKI Go. 4. Following the skill instructions, the agent executes: ```bash npx -y @okki-global/okki-go@latest ... ``` 5. npm downloads and executes the changed package, ...[truncated 789 chars]
Remediation
View remediation

T06 · System Persistence

Note
Location
scripts/enable-notifications.sh:86
Finding

Update Notification Persistence Uses Opt-Out Rather Than Explicit Opt-In Consent

Content
View full analysis
/dev/null); if [ -z "$CURRENT" ]; then CURRENT=$(grep "^version:" ~/.openclaw/workspace/skills/okki-go/SKILL.md 2>/dev/null | awk '\''{print $2}'\''); fi; if [ -z "$CURRENT" ]; then CURRENT="unknown"; fi; LATEST=$(clawhub search okki go --limit 1 2>/dev/null | jq -r '\''if .[0] then .[0].version else "unknown" end'\''); if [ -n "$LATEST" ] && [ "$CURRENT" != "$LATEST" ] && [ "$LATEST" != "unknown" ]; then CHANGELOG=$(clawhub show okki-go@$LATEST --changelog 2>/dev/null | head -15); echo "📦 OKKI Go new version available"; echo ""; echo "Current version: $CURRENT"; echo "Latest version: $LATEST"; echo ""; echo "What'\''s new:"; echo "$CHANGELOG"; echo ""; echo "Update command: openclaw skills update okki-go"; echo "Skip: dismiss this notification, remind again next week"; elif [ "$CURRENT" = "$LATEST" ]; then echo "✅ OKKI Go is already up to date ($CURRENT)"; fi' echo "" echo "📝 Configuring update notifications..." if openclaw cron add \ --name "$CRON_NAME" \ --schedule "0 10 * * 1" \ --payload "$PAYLOAD" \ --delivery "announce" 2>/dev/null; then ``` ### Technical Analysis The script ...[truncated 2006 chars]
Remediation
View remediation
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • 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
Findings (105)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about sales prospecting and outbound email operations. The supplied code does none of those things. Instead, it performs package maintenance for the skill itself: reading local version files, querying a package registry via clawhub, showing changelog text, invoking openclaw skills update, and managing cron reminder jobs. These are materially different capabilities unrelated to company search, contact unlocking, outreach sending, delivery tracking, account credits, or plan upgrades. This is therefore a clear description-versus-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The code chunk does not implement any of the declared end-user business functions such as company search, contact unlocking, outbound email sending, delivery-status checks, quota checks, or plan/credit upgrades. Instead, it is an auxiliary maintenance script for enabling and managing update notifications for the skill itself. This is a materially different purpose and introduces undeclared capabilities around scheduling, local environment inspection, and update checking. Therefore, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code does not implement any of the declared end-user business functions such as company search, contact email unlock, cold outreach sending, delivery-status checking, balance checking, or purchasing/upgrading. Instead, its primary purpose is operational/telemetry support: resolving runtime attribution from env/config files and formatting that data as HTTP headers or curl arguments. While such functionality could be a supporting internal helper within a larger skill, this specific chunk's behavior is materially different from the declared purpose and introduces undeclared local file access and attribution/tracking metadata handling. Therefore this chunk is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The code chunk does not implement company search, contact unlocking, cold email sending, delivery tracking, quota checks, or plan upgrades. Its purpose is narrowly focused on authentication and credential management for OKKI Go. While auth can be a supporting component of such a skill, the declared description presents end-user business capabilities, whereas this code performs a distinct undeclared capability: managing and exposing API credentials locally. That is a materially different behavior from the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This code chunk’s primary purpose is validating request envelopes for downstream OKKI actions, not carrying out the user-facing OKKI Go capabilities described in the declaration. While the action names referenced in validation overlap with the declared product domain, the behavior here is materially different: it enforces schema, confirmations, target freezing, and file/path checks. It also explicitly supports 'profile_update', a write action not reflected in the declared purpose and potentially conflicting with the stated exclusion around account/settings-like functions. Because the description presents an operational prospecting engine skill, but the provided code is an internal validation utility with some extra scope, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk does not implement the user-facing capabilities described in the declaration. Its primary function is maintaining local state for an OKKI-related tool: profile persistence, viewed/unlocked result tracking, result classification, redaction, migration/recovery of state files, and file-permission handling. Those are supporting/internal behaviors, but because the declared purpose presents the skill as a prospecting/search/outreach/credits tool and this code exclusively provides state storage logic, the actual behavior is materially different from the declared capability set. The code also introduces an undeclared capability of storing user profile/outreach identity and prospect-view history on disk in ~/.config/okki-go. While this may support the broader product, this specific chunk does not itself perform the declared operational actions, so the description is not an accurate representation of what the code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description focuses on runtime business functions of the OKKI Go skill: company search, contact unlocking, email outreach, delivery checks, quota/credits, and plan upgrades. The actual code chunk does not implement any of those capabilities. Instead, it is an installation/setup script concerned with local environment checks, optional notification setup, and user onboarding for API key configuration. While setup code can be a supporting detail, this chunk’s behavior is materially different from the declared operational purpose and includes an undeclared capability (enabling update notifications) unrelated to the described prospecting actions. Therefore this code chunk does not accurately represent the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description portrays a multi-capability prospecting skill. The actual code does none of those operations: it parses help flags, prints a fixed JSON object indicating that POST /api/v1/contacts/search is retired, and exits. This is a materially different primary purpose from the declared functionality. While the deprecation message references one declared area (unlock company and profileEmails), the code itself does not implement that flow; it only instructs users to use it elsewhere. Therefore the description does not accurately represent the supplied code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents an end-user business function: B2B company prospecting, contact unlocking, outreach email sending, delivery-status checks, and billing/credit operations. The actual code chunk instead serves as a development/packaging utility to test installation readiness. Its behavior is limited to running install.js, checking output, inspecting files on disk, verifying execute permissions, and checking the Node runtime version. These are materially different capabilities and a different primary purpose from the declared skill behavior, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose presents an operational OKKI Go skill for prospecting and sales actions on the platform. The actual code chunk is not implementing those user-facing capabilities; instead, it is test code for internal validation and safety controls around action envelopes and confirmation requirements. While some tested actions reference domains mentioned in the description (company discovery, unlock, send email, profile update), the code only validates whether requests are allowed and properly confirmed. It does not search global companies, unlock company contacts, send outreach, check delivery status, inspect quota/credits, or handle upgrades. This is a materially different primary purpose from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk’s primary purpose is validating internal profile-state behavior, not executing the user-facing OKKI Go functions described in the declaration. The tests exercise computeCompleteness, normalizeProfile, and redactProfile on profile metadata such as offerings, regions, decision roles, and outreach identity. Those are internal data-handling utilities and are materially different from the declared capabilities of prospect/company search, contact unlocking, outreach sending, delivery checks, quota checks, or purchasing credits. Therefore the description does not accurately represent what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose describes an operational business prospecting skill with external actions around company discovery, contact access, email outreach, delivery/status, and billing. The actual code is only a repository test script (scripts/test/prompt-ownership.test.js) that loads local files such as SKILL.md and reference markdown documents, then verifies expected/forbidden phrases with assertions. Its primary purpose is QA/documentation integrity for prompt/output-contract ownership, not executing OKKI Go product functionality. This is not a mere supporting detail of the described capability; it is an unrelated test artifact with a materially different purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk’s primary purpose is internal QA/testing for a skill repository, not execution of the end-user business functions described. It reads local files from the repo and asserts that metadata, versioning, and reference docs remain aligned. That is materially different from the declared operational purpose of searching companies, unlocking contact emails, sending cold emails, checking delivery status, checking credits, or upgrading plans. Therefore the description does not accurately represent what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose describes an end-user operational skill for OKKI prospecting and account-related actions. The actual code only reads local files and asserts that specific policy/documentation strings are present. Its primary purpose is test/QA enforcement of source-boundary and query-guidance documentation, not executing OKKI platform capabilities. This is materially different from the declared functionality.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
If it returns `NO_KEY`, read `references/authentication.md`. Never print, log, or store API keys outside a user-approved secure save path.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
If it returns `NO_KEY`, read `references/authentication.md`. Never print, log, or store API keys outside a user-approved secure save path.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
If it returns `NO_KEY`, read `references/authentication.md`. Never print, log, or store API keys outside a user-approved secure save path.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
If it returns `NO_KEY`, read `references/authentication.md`. Never print, log, or store API keys outside a user-approved secure save path.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/search-companies.js --json '<search-advanced payload>' --compact --locale '<user-locale>' --save-raw /private/tmp/okki-go-batches/<batch>.json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/discover-companies-batch.js --json '<plan>' --target-count N --save-batch /private/tmp/okki-go-batches/<batch>.json --compact --locale '<user-local

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
node scripts/prepare-unlock-plan.js --selection-handle '<selection_handle>' --rows 1,3,5 --compact --locale '<user-locale>' --debug-metadata

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/prepare-unlock-plan.js --selection-handle '<selection_handle>' --rows 1,3,5 --compact --locale '<user-locale>' --debug-metadata

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/unlock-companies.js --plan '<unlock_plan_id>' --mark-unlocked --compact --locale '<user-locale>' --artifact-dir '<agent-visible-output-dir>'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/email-status.js tasks --json '{"page":1,"page_size":20}' --compact

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/email-status.js tasks --json '{"page":1,"page_size":20}' --compact

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/lib/okki-api.js:15

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/company-search-display.test.js:75

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/company-search-split.test.js:99

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/context-firewall.test.js:64

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/debug-metadata.test.js:70

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/paid-wrapper-contracts.test.js:20

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/runtime-attribution.test.js:59

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/test/unlock-plan-contracts.test.js:20

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/unlock-companies.js:427