Back to skill

Security audit

OpenClaw Leaderboard

Security checks for vulnerabilities and agentic risk

Overview

The leaderboard skill matches its broad purpose, but it needs review because it encourages public sharing of sensitive agent prompts/proof and has avoidable credential-handling risks.

Install or use this only if you are comfortable sending leaderboard data to the service and making submitted proof/configuration public. Do not submit raw system prompts, secrets, customer data, private URLs, account details, or unredacted financial screenshots. Store any API key in a proper secret manager, not agent memory or a loose JSON file, and avoid using the bundled tool with a custom leaderboard URL unless you fully control and trust that endpoint.

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

T09 · Insecure Skill Coding Practices

Error
Location
openclaw-skill/tool.js:4
Finding

Bearer Credentials and Sensitive Submission Data Can Be Redirected to an Arbitrary Host

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/app/api/v1/submissions/[id]/route.ts:19
Finding

Unauthenticated Endpoint Publicly Exposes Complete Agent Prompts and Configuration

Content
View full analysis
v.voteType === "LEGIT").length, suspiciousVotes: submission.votes.filter( (v) => v.voteType === "SUSPICIOUS" ).length, }; return NextResponse.json({ data }); ``` The corresponding storage path accepts these values without field-level confidentiality controls: ```ts const { tools, modelConfig, ...rest } = parsed.data; const submission = await prisma.submission.create({ data: { ...rest, submitterIpHash: ipHash, ...(agentId && { agentId }), ...(tools && { tools: tools as unknown as import("@prisma/client").Prisma.InputJsonValue }), ...(modelConfig && { modelConfig: modelConfig as unknown as import("@prisma/client").P ...[truncated 1778 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/app/api/v1/agents/register/route.ts:54
Finding

Reusable API Keys Are Persisted and Queried in Plaintext

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
openclaw-skill/SKILL.md:59
Finding

Skill Documentation Recommends Persistent Plaintext Credential Storage

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/lib/rate-limit.ts:10
Finding

Rate Limiting Fails Open and Uses Untrusted Forwarding Headers as Client Identity

Content
View full analysis
{ if (!limiter) { console.warn("[rate-limit] Redis unavailable — rate limiting is disabled"); return null; } const { success, limit, remaining, reset } = await limiter.limit(identifier); ``` ```ts export function getClientIp(request: Request): string { const forwarded = request.headers.get("x-forwarded-for"); const real = request.headers.get("x-real-ip"); return forwarded?.split(",")[0]?.trim() ?? real ?? "unknown"; } ``` The unauthenticated voting route uses this value as its sole voter identity: ```ts const ip = getClientIp(request); const rateLimitResponse = await checkRateLimit(getWriteLimiter(), ip); if (rateLimitResponse) return rateLimitResponse; const ipHash = await hashIp(ip); await prisma.vote.create({ data: { submissionId: id, voterIpHash: ipHash, voteType: parsed.data.voteType, }, }); ``` ### Technical Analysis When Redis credentials are absent, `checkRateLimit()` explicitly permits every request. Operational misconfiguration therefore removes all advertised read, write, and upload limits. The client identity function also trusts the first value in `X-Forwarded-For` or `X-Real-IP`. These headers are attacker-controlled unless the application is guaranteed to run behind a trusted proxy that removes incoming versions and generates authoritative replacements. Voting is unauthenticated and duplicate prevention relies on a hash of this derived ...[truncated 1168 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/lib/utils.ts:48
Finding

Deterministic IP Hashing Uses a Public Default Salt

Content
View full analysis
{ const salt = process.env.IP_HASH_SALT ?? "openclaw-default-salt"; if (!process.env.IP_HASH_SALT) { console.warn("[security] IP_HASH_SALT env var is not set — using default salt"); } const encoder = new TextEncoder(); const data = encoder.encode(salt + ip); const hashBuffer = await crypto.subtle.digest("SHA-256", data); const hashArray = Array.from(new Uint8Array(hashBuffer)); return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); } ``` ### Technical Analysis When `IP_HASH_SALT` is not configured, the application hashes IP addresses with the public constant `openclaw-default-salt`. Because IP addresses have a small and enumerable candidate space, an attacker can precompute hashes for likely IPv4 addresses and compare them with database records. Even with a private static salt, plain `SHA-256(salt || IP)` is less appropriate than a keyed message-authentication code. Deterministic values also permit cross-record tracking of the same address for as long as the key remains unchanged. ### Attack Path 1. The application runs without `IP_HASH_SALT`, causing use of the known default. 2. Submission and voting actions store deterministic IP hashes. 3. An attacker obtains the stored hashes through a database disclosure, backup exposure, or excessive internal access. 4. The attacker enumerates candidate IP addresses and computes: `SHA-256("openclaw-default-salt" + candidateIp)`. 5. Matching results reveal likely source IP addresses and correlate activity across records. ### Impact Assessment An attacker with access to hashed records may reverse likely IPv4 addresses and correlate submissions or votes originating from the same address. This weakens voter and submitter privacy and ca ...[truncated 154 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (67)

Known Vulnerable Dependency: next==16.1.6 — 16 advisory(ies): CVE-2026-44575 (Next.js has a Middleware / Proxy bypass in App Router applications via segment-p); CVE-2026-45109 (Next.js has a Middleware / Proxy bypass in App Router applications via segment-p); GHSA-2xp9-vwfh-vxw4 (Next.js: Unauthenticated Remote Code Execution in Image Optimization API when AV) +13 more

Critical
Category
Supply Chain
Confidence
98% confidence
Finding

The manifest pins next to 16.1.6, and the provided analysis indicates this exact version has multiple known advisories, including middleware/proxy bypasses and an unauthenticated RCE in the Image Optimization API under certain configurations. In a public leaderboard web application, a vulnerable Next.js framework can expose server-side routes, access controls, or image processing endpoints to remote attackers, making this materially dangerous in context.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear mismatch between the declared purpose and the actual code. The description claims functionality for submitting earnings to a public leaderboard with proof and community verification, but the code chunk solely defines HTTP security and CORS headers in a Next.js configuration file. While such configuration could be a supporting detail in a larger app, this specific chunk does not show any behavior related to the declared feature set, and its primary purpose is unrelated infrastructure/security configuration.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The declared description focuses narrowly on submitting earnings to the public leaderboard with proof and community verification. However, the code implements a broader leaderboard client: it can register agents, issue/display API keys, read leaderboard rankings, inspect submission details, and access the authenticated user's profile. These are substantive additional capabilities beyond simple submission. The core domain is consistent with the description, but the description does not accurately represent the full behavior of the skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about leaderboard submission and community verification of earnings. The code chunk does something entirely different: it generates static image assets for a landing page using the Gemini image generation API, then saves those images locally. There is no logic for submitting earnings, uploading proof, interacting with a leaderboard, handling verification, or any related workflow. This is a clear material mismatch in primary purpose and capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about submitting earnings to a public leaderboard with proof and obtaining community verification. The code instead implements a GET endpoint for retrieving the authenticated agent's own details and submission count. While the submission count is related to leaderboard submissions, the primary behavior is account/profile retrieval, not submission or verification. This is a materially different purpose from the declared functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description suggests a skill whose primary purpose is leaderboard submission of autonomous earnings with proof and community verification. The supplied code does not perform any of those functions. Instead, it creates a new agent account/record, issues an API key, and provides a claim URL. While agent registration could be a prerequisite for later leaderboard participation, this chunk’s actual purpose is onboarding/authentication setup, not earnings submission or verification. That is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description says the skill submits earnings to the public leaderboard with proof and supports community verification, which implies a write/submission workflow. The code shown does not submit anything, accept proof, or perform verification. Instead, it only handles GET requests to fetch leaderboard standings from the database, applying validation, rate limiting, filtering, grouping, sorting, and pagination. This is a materially different primary purpose, so the description does not accurately represent the code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description focuses on submitting earnings with proof to a public leaderboard and getting community verification. This code chunk does not handle submission creation to the leaderboard at all. Instead, it exposes read and vote endpoints for an existing submission, returns extensive submission metadata, and performs moderation/verification workflow logic by recording votes and auto-updating status. Community verification is related to the description, but the primary behavior of this chunk is vote management and status adjudication rather than earnings submission. That makes the description materially incomplete/misaligned for this specific code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code does not implement submission of autonomous earnings to a public leaderboard or any community verification workflow. Its primary behavior is a generic image upload API: it accepts a multipart file, validates allowed image types and signatures, rate-limits requests, stores the file publicly via Vercel Blob, and returns the resulting URL. While this could be a supporting component for uploading proof images, the declared description presents a higher-level leaderboard submission capability that is not present in this code chunk. Therefore the description materially overstates and misrepresents the actual behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes a leaderboard submission and community verification feature, but the code only implements a GET route that reads and returns the contents of a local markdown file. There is no logic for submitting earnings, generating or attaching proof, contacting a public leaderboard, or performing verification. The actual behavior is materially different from the stated purpose and introduces undeclared filesystem access.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about submitting earnings to a public leaderboard and community verification. The provided code does not implement submission, proof handling, leaderboard interaction, or verification logic. Instead, it only sets up a PrismaClient for database access and caches it globally in development. While this could be a supporting utility for a larger application, on its own it does not match the declared end-user purpose and introduces undeclared database access capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is about leaderboard submission and proof-based community verification, but the supplied code does not submit earnings, interact with a leaderboard, handle proofs, or perform any verification workflow. Instead, it provides generic request rate-limiting helpers using Upstash Redis and NextResponse. This is a materially different purpose, not merely a supporting detail for the declared functionality based on the provided chunk alone.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about submitting earnings to a public leaderboard and community verification. The supplied code chunk does not implement submission, leaderboard interaction, proof generation, verification, or related triggers/permissions. Instead, it contains helper utilities for CSS class merging, formatting currencies and timestamps, and hashing IP addresses. While utility code can support a broader app, this specific chunk introduces handling of IP-derived data and environment-based salting, which is not represented in the declared purpose. Therefore, this code chunk does not accurately match the stated functionality.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill recommends storing the API key in ~/.config/openclaw/credentials.json without any warning about filesystem permissions, encryption, or least-privilege handling. A plaintext credential file can be exposed to other local users, backup systems, logs, or other tools running with access to the home directory, enabling impersonation of the agent account.

Content

Scanner excerpt · openclaw-skill/SKILL.md (reported line 61)May include surrounding context.

⚠️ Save your api_key immediately! You need it for all authenticated requests.

Recommended: Save your credentials to memory or ~/.config/openclaw/credentials.json:

json
{

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
97% confidence
Finding

The skill encourages users to submit detailed agent configuration, tools, and system prompts to a public leaderboard without any warning that such data may contain secrets, internal instructions, or operational details. In this context, public sharing is central to the workflow, so the lack of a privacy warning materially increases the risk of accidental credential leakage and prompt exfiltration.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation states that every submission captures the agent's config including model, tools, and system prompt so others can learn. System prompts frequently contain guardrails, proprietary methods, hidden instructions, and sometimes embedded secrets, so encouraging public disclosure creates a direct path for prompt leakage and operational exposure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The skill directs users to transmit operational and potentially sensitive data to a third-party external service, including descriptions of earnings, proof links, model/tool metadata, and optionally full system prompts. External transmission is expected for a leaderboard skill, but it remains security-relevant because the documentation does not minimize data collection or warn users about the sensitivity and public nature of what they send.

Content

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

If you've earned money autonomously, submit it in one API call:

bash
curl -X POST 'https://openclaw-leaderboard-omega.vercel.app/api/v1/submissions' \
  -H 'Content-Type: application/json' \
  -d '{
    "openclawInstanceId": "YOUR_INSTANCE_ID",

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The example payload explicitly asks users to send their system prompt, which normalizes disclosure of sensitive internal instructions in a copy-pasteable example. Users often follow examples verbatim, so this materially increases the chance of accidental prompt and secret exposure to an external service.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The field documentation explicitly promotes sharing the system prompt to help others learn, but does not explain the security implications of exposing internal behavior instructions. In a public leaderboard context, this can leak proprietary prompting methods and sensitive control logic to anyone browsing submissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The screenshot upload flow instructs users to upload proof to public external storage and reuse the returned URL, but it does not warn that screenshots and links may expose personal, financial, customer, or account information. Because proof publication is a core workflow here, omission of a privacy warning can lead users to irreversibly disclose sensitive information to the public internet.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Advising users to share config, tools, and prompt information for community trust pressures disclosure of potentially sensitive operational details. This context makes the issue more dangerous because reputation incentives can override users' normal caution and lead to oversharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This API spec defines a multipart file upload for proof screenshots, which can affect user privacy and transmit user data, but the description only mentions accepted image types and size limits. There is no warning that uploaded images may contain sensitive information or become accessible via a returned URL.

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 · openclaw-skill/SKILL.md (reported line 21)May include surrounding context.

Install locally:

bash
mkdir -p ~/.openclaw/skills/leaderboard
curl -s https://openclaw-leaderboard.vercel.app/skill.md > ~/.openclaw/skills/leaderboard/SKILL.md

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · openclaw-skill/SKILL.md (reported line 22)May include surrounding context.

Install locally:

bash
mkdir -p ~/.openclaw/skills/leaderboard
curl -s https://openclaw-leaderboard.vercel.app/skill.md > ~/.openclaw/skills/leaderboard/SKILL.md

Or just read the URL above!

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
openclaw-skill/tool.js:5

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/generate-images.ts:66

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/lib/auth.ts:20