Back to skill

Security audit

GoHighLevel CRM Automation

Security checks for vulnerabilities and agentic risk

Overview

This GoHighLevel CRM skill is mostly purpose-aligned, but it asks for broad live CRM authority and can send customer messages or modify records without enforceable safeguards.

Review this carefully before installing. Use a least-privilege GoHighLevel token, avoid placing or echoing secrets in shell commands or logs, and do not allow autonomous use of message sending, workflow triggering, contact updates, opportunity changes, or invoice/payment-related scopes without an external approval and compliance layer you control.

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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ghl_api.py:337
Finding

API credential material is disclosed by the health command

Content
View full analysis
12 else f" API Key: {API_KEY}") print(f" Location: {LOCATION_ID}") ``` ### Technical Analysis The health command prints the first eight and last four characters of a normal API token. If the token is 12 characters or shorter, it prints the complete token. It also prints the GoHighLevel location identifier. Diagnostic output can be retained in shell history captures, CI logs, agent transcripts, monitoring systems, or support bundles. Even partial secret disclosure unnecessarily reduces the effective secrecy of the token and can help correlate it with material obtained from another source. A short token would be exposed completely. Displaying token content is not necessary to verify whether the credential is configured or whether an authenticated API request succeeds. ### Attack Path 1. An operator or automated agent invokes the `health` command. 2. The command writes token material and the location ID to standard output. 3. An execution environment, agent framework, CI system, or logging service retains that output. 4. An attacker with access to the retained logs extracts the disclosed material. 5. If the complete token was printed, the attacker can authenticate directly to GoHighLevel. If only a fragment was printed, it can assist token identification, correlation, or recovery when combined with another disclosure. ### Impact Assessment For ordinary long tokens, this issue discloses 12 token characters and the associated location identifier but does not independently provide complete authentication. For short tokens, it discloses the complete Bearer credential. A complete credential would provide all GoHighLevel permissions granted to the private integration, potentially includ ...[truncated 137 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ghl_api.py:230
Finding

Outbound CRM message content and contact identifiers are written to logs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ghl_api.py:230
Finding

Outbound messaging bypasses the documented TCPA safety guardrail

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:87
Finding

Setup instructions request API permissions beyond implemented functionality

Content
View full analysis
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tainted flow: 'req' from os.environ.get (line 93, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/ghl_api.py (reported line 94)May include surrounding context.

python
for attempt in range(MAX_RETRIES):
        try:
            req = urllib.request.Request(url, data=data, headers=headers, method=method)
            with urllib.request.urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            if e.code == 429:

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description overclaims capabilities and safety properties that are not evidently implemented, including full read/write support, real-time behavior, and guardrail enforcement. Security-relevant misrepresentation is dangerous because operators may trust the skill to enforce restrictions or support workflows it does not actually implement, leading to unsafe automation decisions.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The usage instructions direct users to read API credentials from a local .env file and export them into the shell for use by the skill. Exposing credential-loading patterns inside an agent skill is sensitive because it normalizes secret access, increases the chance of accidental leakage through logs/history, and gives the skill operational access to a high-privilege CRM token.

Content

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

All commands are run via the included Python CLI at {baseDir}/scripts/ghl_api.py:

bash
export GHL_API_KEY=$(grep GHL_API_KEY ~/.openclaw/.env | cut -d= -f2)
export GHL_LOCATION_ID=$(grep GHL_LOCATION_ID ~/.openclaw/.env | cut -d= -f2)

# Test connection

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This line continues the credential export workflow for a second secret, reinforcing a pattern where the skill depends on direct access to local secret material. For a CRM integration with broad write access, such credential handling materially raises the risk of unauthorized account actions if the environment or shell session is exposed.

Content

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

bash
export GHL_API_KEY=$(grep GHL_API_KEY ~/.openclaw/.env | cut -d= -f2)
export GHL_LOCATION_ID=$(grep GHL_LOCATION_ID ~/.openclaw/.env | cut -d= -f2)

# Test connection
python3 {baseDir}/scripts/ghl_api.py health

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/ghl_api.py (reported line 69)May include surrounding context.

python
def check_env():
    if not API_KEY:
        print("ERROR: GHL_API_KEY not set.")
        print("Run: export GHL_API_KEY=$(grep GHL_API_KEY ~/.openclaw/.env | cut -d= -f2)")
        sys.exit(1)
    if not LOCATION_ID:
        print("ERROR: GHL_LOCATION_ID not set.")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/ghl_api.py (reported line 73)May include surrounding context.

python
def check_env():
    if not API_KEY:
        print("ERROR: GHL_API_KEY not set.")
        print("Run: export GHL_API_KEY=$(grep GHL_API_KEY ~/.openclaw/.env | cut -d= -f2)")
        sys.exit(1)
    if not LOCATION_ID:
        print("ERROR: GHL_LOCATION_ID not set.")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises and requires sensitive capabilities (environment variable access and outbound network access) but does not declare an explicit tool scope such as permissions or allowed-tools. This weakens platform-side containment and makes it harder to enforce least privilege or review what the skill is actually allowed to do before execution.

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 3)May include surrounding context.

md
---
name: ghl-crm-mastery
description: Full read/write access to GoHighLevel CRM via API v2. Contacts, conversations, notes, opportunities, calendars, tags, tasks, forms, workflows, payments, and invoices. Includes rate-limit retries, safety guardrails, and real-time conversation support.
version: 1.3.0
author: SetupClaw.Tech
homepage: https://setupclaw.tech

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

These commands perform live mutations against CRM records, such as updating contacts and modifying tags, without any confirmation, dry-run mode, or explicit warning to the operator. In an agent context, this raises the risk of accidental or prompt-induced modification of customer data at scale.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring states that TCPA compliance is enforced by another layer, but this function itself sends outbound messages without checking consent, channel restrictions, quiet hours, or approved use. In an agent skill with live CRM write access, that mismatch is dangerous because callers may rely on the claim and trigger unauthorized SMS/email outreach to real customers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script can send customer messages, create notes, update opportunities, and trigger workflows immediately, all of which are state-changing and externally visible actions. In this skill's context of full read/write CRM access, absence of confirmation or policy gating makes accidental spam, business-logic abuse, or unauthorized workflow execution substantially more dangerous.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The health command prints a partial private integration token to stdout. Even truncated secrets increase exposure in shared terminals, logs, agent transcripts, or observability systems, and can aid token identification or correlation during incident response by an attacker.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.