Back to skill

Security audit

Google-analytics-GA4

Security checks for vulnerabilities and agentic risk

Overview

This GA4 skill largely matches its stated purpose, but it needs Review because it can send analytics reports to an arbitrary webhook and its credential-storage guidance is unsafe.

Install only if you are comfortable granting the skill read access to GA4 data through a narrowly scoped Viewer service account. Keep the service-account JSON outside the skill or add your own ignore/secret-scanning protections, and do not set DINGTALK_WEBHOOK unless you have verified the exact destination and are willing to send the generated analytics report there.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
traffic_source_report.py:317
Finding

Unrestricted Webhook Destination Can Disclose Google Analytics Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:37
Finding

Credential Storage Instructions Rely on a Missing Git Ignore Rule

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:2
Finding

Unbounded Dependency Versions Prevent Reproducible and Auditable Installation

Content
View full analysis
=0.19.0 # Google Auth (pulled in transitively) google-auth>=2.0.0 # Optional: DingTalk outbound webhook in traffic_source_report.py requests>=2.28.0 ``` ### Technical Analysis All declared dependencies use only a lower version bound. A future installation may therefore resolve to versions that did not exist when the Skill was reviewed, along with changed transitive dependencies. No typosquatted package, untrusted package index, direct URL dependency, or known malicious package was identified in the audited file. The named packages are recognizable mainstream dependencies. The weakness is that installation is not reproducible and future dependency code is implicitly trusted without review. Python packages and their dependencies execute code in the environment where they are imported and may run build-related code during installation. Consequently, a compromised future release or unexpectedly changed dependency graph could affect the confidentiality and integrity of the host process. ### Attack Path 1. A user installs the project dependencies at a later date using `pip install -r requirements.txt`. 2. The resolver selects the newest versions satisfying the broad lower bounds. 3. A selected package or transitive dependency has been compromised, contains a newly introduced vulnerability, or makes an incompatible security-relevant change. 4. The package executes during installation or import with the privileges of the user running the Skill. 5. The compromised component can potentially access the same files, environment variables, credentials, and network resources available to that process. This is a supply-chain exposure rather than evidence that the currently named packages are malicious. ### Impact Assessment The maximum theoretical ...[truncated 445 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (36)

Tainted flow: 'url' from os.environ.get (line 333, credential/environment) → requests.post (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 · traffic_source_report.py (reported line 344)May include surrounding context.

python
},
    }

    response = requests.post(url, headers=headers, json=data, timeout=30)
    try:
        result = response.json()
    except Exception:

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The script automatically falls back to a local ga-credentials.json file if present, enabling authenticated access without an explicit credential path from the user. In a skill environment, implicit credential discovery increases the risk of unintended privilege use and unauthorized querying of analytics data if the skill is triggered by an untrusted prompt or caller.

Content

Scanner excerpt · openclaw_ga.py (reported line 27)May include surrounding context.

python
if credentials:
        cmd.extend(["--credentials", credentials])
    else:
        default_creds = os.path.join(SCRIPT_DIR, "ga-credentials.json")
        if os.path.exists(default_creds):
            cmd.extend(["--credentials", default_creds])

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · EXAMPLES.md (reported line 204)May include surrounding context.

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · QUICK_REFERENCE.md (reported line 12)May include surrounding context.

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 43)May include surrounding context.

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 57)May include surrounding context.

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · RESEARCH_SUMMARY.md (reported line 118)May include surrounding context.

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · full_test.py (reported line 11)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · ga_query.py (reported line 291)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · ga_query.py (reported line 292)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · ga_query.py (reported line 363)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · temp_test.py (reported line 11)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · test_connection.py (reported line 36)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · test_connection.py (reported line 40)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · test_connection.py (reported line 46)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · traffic_source_report.py (reported line 16)May include surrounding context.

python
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
creds_path = os.path.join(SCRIPT_DIR, "ga-credentials.json")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = creds_path

print(f"Credentials path: {creds_path}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
### 3. Grant GA4 access

1. Open [Google Analytics](https://analytics.google.com/).  
2. Select the property.  
3. **Admin** (gear) → **Property access management**.  
4. **Add users** → enter the service account email (`…@….iam.gserviceaccount.com`).

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documentation discloses optional DingTalk webhook notifications and a traffic source reporting capability that are not described in the main capability list, which creates a transparency gap around data flows. In a security-sensitive analytics skill, undocumented outbound integrations can lead users to unintentionally transmit analytics-derived data to third-party endpoints without realizing the feature exists.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Mentioning DingTalk webhook support without a clear warning about outbound transmission understates the privacy and data-handling implications of the skill. Analytics reports can contain sensitive business intelligence or user-segmentation data, so silent or poorly disclosed export paths increase the risk of unintended data leakage to external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This Python file creates a GA4 client and sends multiple report requests to Google's Analytics API. Although the script is described as a manual integration test, it does not explicitly warn the user that running it will transmit account-scoped identifiers and query live analytics data over the network.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.