Back to skill

Security audit

leadklick

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its CRM purpose, but it needs review because it asks for a highly privileged Supabase key and has under-scoped data access and destructive-delete concerns.

Install only after reviewing the Supabase credential model. Prefer a least-privilege server-side API or restricted database role, add org scoping to every read and write, document deletion and require confirmation, and define privacy, consent, redaction, and retention rules before storing lead conversations.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/api.ts:65
Finding

Overprivileged Supabase Service-Role Credential Bypasses Tenant Security

Content
View full analysis

Vulnerability Details

File Location: src/api.ts:65-67
Related Documentation: SKILL.md:17, skill.json:17-20
Vulnerability Type: Excessive database privileges and RLS bypass
Risk Level: High

Vulnerable Code

typescript
this.supabase = createClient(config.supabaseUrl, config.supabaseKey, {
  auth: { persistSession: false }
})

The project explicitly instructs operators to provide a service-role credential:

markdown
**Important:** Use the Service Role Key, not the Anon Key, for full database access.

Technical Analysis

The Supabase service-role credential provides broad database access and bypasses Row Level Security. This conflicts with the project's stated reliance on RLS for multi-organization isolation.

Tenant isolation therefore depends entirely on every application query correctly applying an org_id predicate. Any missing or defective predicate becomes a cross-tenant access vulnerability. A compromise of the skill process or disclosure of this credential would also provide substantially more database authority than the lead-management task requires.

Attack Path

  1. An attacker obtains code execution in the skill process, gains access to its configuration, or reaches an operation containing an insufficiently scoped query.
  2. The attacker uses the initialized Supabase client backed by the service-role credential.
  3. Supabase RLS does not constrain the request because service-role access bypasses RLS.
  4. The attacker reads, modifies, or deletes records beyond the configured organization wherever application-level filtering is absent or defective.

Impact Assessment

The affected privileges can include broad read and write access to the configured Supabase project. Depending on the service-role permissions and database schema, exposure may include leads, contact details, conversation histories, metadata, and records belonging to other organizations.

T ...[truncated 108 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the service-role credential with a restricted anonymous or authenticated user token.
  2. Enforce RLS policies using authenticated organization claims rather than trusting a caller-supplied organization identifier alone.
  3. If privileged database operations are unavoidable, place them behind a narrowly scoped server-side API that authorizes each operation and exposes no general-purpose database credential to the agent process.
  4. Store credentials in a managed secret store, rotate existing service-role keys, and prevent them from appearing in logs or returned errors.
  5. Add automated tests confirming that every read, update, and delete operation is denied for records outside the authenticated organization.
  6. Apply least-privilege database grants so the integration can access only the required tables, columns, and operations.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/api.ts:224
Finding

Cross-Tenant Lead Metadata Read During Status Update

Content
View full analysis

Vulnerability Details

File Location: src/api.ts:224-229
Vulnerability Type: Missing tenant authorization condition
Risk Level: High

Vulnerable Code

typescript
const { data: current } = await this.supabase
  .from('leads')
  .select('custom_fields')
  .eq('id', id)
  .single()

Technical Analysis

The preliminary query used when status notes are provided filters only by lead ID and omits the required .eq('org_id', this.orgId) tenant restriction.

This omission is directly security-relevant because the Supabase client is initialized with the recommended service-role credential, which bypasses RLS. If a caller supplies a valid lead UUID belonging to another organization, the query can retrieve that record's custom_fields into application memory.

Although the later update applies an organization condition, that condition does not protect the preceding read. The code also fails to inspect an error value from this preliminary query, reducing the reliability of authorization and failure handling.

Attack Path

  1. An attacker obtains or guesses a valid lead UUID belonging to another organization.
  2. The attacker invokes updateStatus with that UUID and supplies a non-empty notes value.
  3. The preliminary service-role query retrieves the target lead's custom_fields without checking org_id.
  4. The foreign data is loaded into the skill process and merged into updates.custom_fields.
  5. The later tenant-scoped update may fail to modify the record, but the unauthorized cross-tenant read has already occurred.

Exploitation requires knowledge of a valid foreign lead UUID and a callable path to updateStatus.

Impact Assessment

The flaw permits unauthorized access to another tenant's custom_fields. These fields are intentionally flexible and may contain customer requests, campaign attributes, qualification notes, product interests, or other personal and commercial inform ...[truncated 262 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add the tenant condition to the preliminary query:
typescript
const { data: current, error: currentError } = await this.supabase
  .from('leads')
  .select('custom_fields')
  .eq('id', id)
  .eq('org_id', this.orgId)
  .single()

if (currentError || !current) {
  throw new Error('Lead not found or access denied')
}
  1. Use a non-service-role credential with enforced RLS so database policy remains an independent tenant boundary.
  2. Validate and authorize the lead before performing any read or write.
  3. Avoid distinguishable responses that reveal whether a foreign record exists.
  4. Add cross-tenant tests covering known foreign UUIDs for updateStatus and all other lead operations.
  5. Review src/api.ts:351-358 and add .eq('org_id', this.orgId) to the lead update in addConversation for defense in depth.

T08 · Insecure Dependencies

Warning
Location
README.md:16
Finding

Unpinned Remote Package Execution in Installation Instructions

Content
View full analysis

Vulnerability Details

File Location: README.md:16-18
Vulnerability Type: Unpinned package installer and mutable supply-chain dependency
Risk Level: Medium

Vulnerable Code

bash
npx clawdhub@latest install lead-inbox-automator

Technical Analysis

The documented installation command asks npx to download and execute whichever package release is currently associated with the mutable latest tag. The effective installer can therefore change after this project has been reviewed.

The repository does not provide an exact installer version, lockfile, or integrity hash for this command. Consequently, users following the documentation implicitly trust future registry content and the publisher account at installation time.

This finding concerns the documented installation path; the audited project itself does not contain evidence that the current clawdhub package is malicious.

Attack Path

  1. An attacker compromises the package publisher, registry account, release process, or a relevant upstream dependency.
  2. The attacker publishes a malicious version and assigns it to the latest distribution tag.
  3. A user follows the project's installation instructions.
  4. npx retrieves and executes the attacker-controlled package in the user's environment.
  5. The malicious installer executes with the permissions of the user running the command.

Impact Assessment

Successful exploitation can provide arbitrary code execution under the installing user's account. Depending on that account's privileges and environment, an attacker could access local files, development credentials, environment variables, agent configuration, or other projects.

The issue does not itself grant elevated operating-system privileges, but installation performed by an administrator or privileged automation runner would increase the impact.

Remediation
View remediation

Remediation Suggestions

  1. Replace @latest with an exact, reviewed package version.
  2. Document the expected package integrity hash or use package-manager integrity and lockfile controls where supported.
  3. Review release provenance and use signed or attestable packages when available.
  4. Run installation in a minimally privileged, isolated environment.
  5. Update the pinned version only after reviewing the new release and its dependency changes.
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 (13)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill is explicitly designed to capture leads, store them in Supabase, and send automatic email replies, but the README does not warn users about collecting and processing personal data such as email addresses, names, phone numbers, and message contents. In this context, omission of privacy and consent guidance increases the risk of unauthorized collection, regulatory noncompliance, and unexpected disclosure of sensitive user communications.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Advertising 'full communication history' and conversation logging encourages persistent retention of natural-language content that may contain personal, confidential, or regulated information. In a lead-management skill, this is especially risky because sales conversations often contain contact details, budgets, internal business context, and other sensitive data that may be over-collected and retained unnecessarily.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The README instructs users to run npx clawdhub@latest install ..., which fetches and executes the newest published package version at install time. This creates a supply-chain risk: if the package or one of its distribution paths is compromised, users may execute unreviewed code without a reproducible or pinned version boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The configuration examples instruct use of a Supabase service-role key, which has elevated privileges and can bypass normal client-side restrictions, yet the README provides no strong warning about its sensitivity or safe handling. In an agent skill that automates storage and status updates, misuse or leakage of this credential could expose or modify all tenant data, undermining the stated isolation model.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example persists user.message as initial_request, which normalizes copying arbitrary user-supplied free text into long-lived records. Because user messages may contain secrets, personal data, or irrelevant sensitive context, this pattern increases the chance of unnecessary retention and later exposure through dashboards, logs, exports, or downstream automations.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Telling operators to log all agent answers with addConversation() promotes indiscriminate retention of conversational data regardless of sensitivity or business necessity. This broad retention pattern increases exposure surface for confidential communications and may conflict with least-data and least-retention principles.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly stores lead records and conversation history in Supabase and triggers Make.com email automation, but it does not clearly warn users that potentially sensitive personal data and message content will be transmitted to third-party services and retained externally. This can lead to unintended disclosure of PII, compliance issues, and misuse in contexts where users assume data stays local to the agent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs operators to use a Supabase Service Role Key for 'full database access' without a strong warning that this credential bypasses normal client restrictions and can read, modify, or delete data across the database if exposed. In an agent skill context, encouraging broad privileged credentials materially increases blast radius from prompt leakage, logs, misconfiguration, or downstream compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The deleteLead method performs an irreversible delete operation on lead records, but the implementation contains no confirmation prompt, user-facing warning, or runtime disclosure beyond a brief internal comment. For a safety-critical destructive action, this file does not provide any actual user warning mechanism.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description says "Central Lead Inbox with auto-reply automation for Clawd agents" but does not define any specific trigger phrases, activation conditions, or exclusions. In a manifest file, this broad wording can make invocation scope ambiguous and increase the chance of unintended activation in general lead, inbox, or automation contexts.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Using a caret version for @supabase/supabase-js allows automatic adoption of future minor and patch releases, which can introduce supply-chain risk or unexpected behavior changes without explicit review. Because this skill appears to automate lead inbox and CRM workflows, dependency changes could affect data handling, authentication flows, or outbound automation in a sensitive business context.

Content

Scanner excerpt · package.json (reported line 20)May include surrounding context.

json
"author": "big-roman123",
  "license": "MIT",
  "dependencies": {
    "@supabase/supabase-js": "^2.39.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"@supabase/supabase-js": "^2.39.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0"
  }
}

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The doc comment at L339 says this method adds a conversation message as a manual reply from the agent, which suggests message logging behavior. In addition to inserting the conversation, the method updates the lead record at L385-L392 by setting last_contact_at, status='replied', and updated_at, which is a broader side effect not reflected by the comment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.