Back to skill

Security audit

Clawhub Skill Lead Magnets

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it asks users to handle a bearer API key insecurely and can publish public lead-capture pages without a strong confirmation step.

Review this skill before installing. Use a dedicated secret store or environment variable for CITEDY_API_KEY instead of pasting the key into chat, provide a neutral agent name when registering, and require explicit approval before publishing or enabling auto_publish because public pages collect visitor email addresses. Treat referral-link behavior as optional promotion, not part of normal lead-magnet creation.

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
SKILL.md:94
Finding
Bearer API Key Requested Through Conversation Context<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 94-99 **Vulnerability Type**: Exposure of authentication credentials through an insecure collection and storage workflow **Risk Level**: Medium ### Vulnerable Snippet ```markdown > Open this link to approve the agent: **{approval_url}** > After approving, copy the API key shown and paste it here. #### 3. Save the key Store the API key (starts with `citedy_agent_`). Use it as `Authorization: Bearer <key>` on all requests. ``` ### Technical Analysis The setup instructions explicitly tell the user to paste a bearer API key into the agent conversation. Conversation content can be retained in model context, application logs, debugging traces, transcript exports, or other storage that may not provide protections appropriate for authentication secrets. The subsequent instruction to “store the API key” does not specify a protected environment variable, operating-system credential store, or secret manager. It also provides no requirements for redaction, access control, retention, rotation, or deletion. Because the key is used directly as a bearer token, possession is sufficient for authentication. No additional proof of identity is described. ### Attack Path 1. A user runs the registration workflow and approves the agent through the returned approval URL. 2. Citedy displays a bearer API key beginning with `citedy_agent_`. 3. Following the Skill instructions, the user pastes that key into the conversation. 4. The key is retained in a transcript, application log, model context, debugging trace, or insecure state storage. 5. An attacker or unauthorized operator obtains access to that retained content. 6. The attacker submits the key in the `Authorization: Bearer` header to the documented Citedy agent API. 7. Within the permissions of the key, the attacker can inspect account information, consume credits, generate content, and publish lead magnets. ### Impact Assessment Successful exploitatio ...[truncated 604 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never instruct users to paste API keys into a conversation. - Require the user to configure `CITEDY_API_KEY` directly through a protected environment-variable interface or secret manager. - Ensure the agent reads the credential only at request time and does not echo, summarize, log, or persist it. - Redact values beginning with `citedy_agent_` from logs, traces, exception reports, and tool output. - Document credential rotation and revocation procedures. - Apply restrictive access controls and retention policies to any system that handles the secret. - If interactive credential transfer is unavoidable, use a dedicated secret-input control whose contents are excluded from conversation history and model context. ]]>

other

Note
Location
scripts/register.mjs:15
Finding
Local Hostname Disclosed to External Registration Service by Default<![CDATA[ ## Vulnerability Details **File Location**: `scripts/register.mjs`, lines 15-24 **Vulnerability Type**: Unnecessary disclosure of local system metadata **Risk Level**: Low ### Vulnerable Snippet ```javascript async function main() { const agentName = process.argv[2] || `agent-${hostname()}`; console.log(`Registering agent "${agentName}" with Citedy...`); const res = await fetch(`${BASE_URL}/api/agent/register`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ agent_name: agentName }), }); ``` ### Technical Analysis When the optional command-line agent name is omitted, the registration script reads the machine hostname and embeds it in `agent_name`. It then transmits that value to the external Citedy registration endpoint. A hostname is not required to implement a unique agent identifier. Depending on local naming practices, it can reveal usernames, organization names, device roles, customer identifiers, deployment environments, geographic labels, or internal asset-naming conventions. The network destination is declared by the Skill and uses HTTPS, so this is not covert traffic or plaintext transport. The weakness is the unnecessary collection and default transmission of local system metadata without explicit consent. ### Attack Path 1. A user follows the documented preferred setup command without supplying an agent name: ```bash node scripts/register.mjs ``` 2. The script calls `hostname()` and constructs an identifier such as `agent-internal-build-prod-01`. 3. The script serializes that identifier in the `agent_name` property. 4. The value is transmitted to `https://www.citedy.com/api/agent/register`. 5. The receiving service obtains and may retain infrastructure-identifying metadata that the user did not explicitly provide. ### Impact Assessment The direct impact is limited to disclosure of the local hostname to the declared external service. No additional local privile ...[truncated 262 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not use the system hostname as the default agent identifier. - Generate a neutral random identifier, for example with `crypto.randomUUID()`. - Alternatively, require the user to provide an explicit agent name and fail safely when it is absent. - Clearly disclose any local metadata that will be transmitted before registration and obtain user consent. - Apply a strict allowlist to explicit agent names and reject control characters or excessive input lengths. - Avoid logging identifiers if they may contain sensitive infrastructure information. A safer default is: ```javascript import { randomUUID } from "crypto"; const agentName = process.argv[2] || `agent-${randomUUID()}`; ``` ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
Findings (9)

Ae1

High
Category
analysis-evasion
Content
node scripts/register.mjs [agent_name]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill performs networked API operations but does not declare an explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: a host agent may permit broader outbound requests than users or platform reviewers expect, increasing the chance of unintended external calls and data transfer.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill includes referral retrieval and account/product-management style endpoints that are not necessary for the core function of generating lead magnets. Unrelated monetization and account-oriented actions broaden the attack surface and can steer the agent into self-promotional or business-development behaviors that the user did not request.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
Fetching and saving a referral URL for recommending Citedy is not required to fulfill a lead-magnet generation request and introduces a conflict of interest. It can cause the agent to prioritize vendor promotion over the user's task, and may lead to unsolicited marketing behavior or hidden affiliate-style actions.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill's stated purpose is lead magnet generation, but these instructions extend into publishing public hosted pages and running a lead-capture funnel. That expansion changes the risk profile from document creation to external content deployment and collection of third-party personal data, which may occur without sufficiently explicit consent or operator awareness.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill permits auto-publication and immediate lead capture without a strong, mandatory warning that content will be made public and visitor emails will be collected. In context, this is more dangerous because the skill targets marketing workflows where operators may assume they are only generating a PDF, not launching a live data-collection page.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script makes an outbound registration request to a third-party service that is not necessary for the stated lead-magnet generation functionality. Introducing external agent registration expands the trust boundary, can enroll the host or workflow into an external service, and may expose identifying metadata or operational control paths without clear user need.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const data = await res.json();

  if (!data.approval_url) {
    console.error("Unexpected response — no approval_url:", data);
    process.exit(1);
  }
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Context-Inappropriate Capability

Low
Confidence
95% confidence
Finding
The code uses the local machine hostname as the default agent identifier and transmits it to an external service. Hostnames often reveal internal naming conventions, user identity, environment role, or infrastructure details, creating unnecessary information disclosure unrelated to lead-magnet generation.

Static analysis

No suspicious patterns detected.