Back to skill

Security audit

Signal Pipeline

Security checks for vulnerabilities and agentic risk

Overview

The skill is a plausible marketing signal collector, but it needs Review because it combines Gmail access, unsafe shell execution, undeclared WeChat/Sogou scraping, and hard-coded agent-memory storage without enough scoping or disclosure.

Review before installing. Use only with a dedicated, least-privilege Gmail account or label, audit or replace the gog shell invocation, remove or disclose WeChat/Sogou scraping, change storage to a project-local configurable directory, and pin dependencies before running it in a real workspace.

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

T09 · Insecure Skill Coding Practices

Error
Location
newsletter_monitor.py:22
Finding

Shell Command Injection in Gmail Newsletter Query Helper

Content
View full analysis
/tmp/gog-injection-proof; # ``` terminates the quoted Gmail search expression, executes a second shell command, and comments out the remaining command text. ### Attack Path 1. An attacker obtains influence over a value passed to `run_gog()`, such as through a future configurable newsletter search, another imported module, or an Agent-generated query. 2. The attacker supplies a search string containing a single quote followed by shell syntax. 3. The formatted string is passed to the system shell because `shell=True` is enabled. 4. The shell executes the inje ...[truncated 876 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
rss_db.py:147
Finding

SQL Query Manipulation Through Interpolated Time-Window Arguments

Content
View full analysis
= datetime('now', '-{} hours') ORDER BY relevance_score DESC, published DESC LIMIT ? """.format(hours) cursor = conn.execute(query, (limit,)) ``` ```python cursor = conn.execute(""" SELECT sentiment, COUNT(*) as count FROM articles WHERE fetched_at >= datetime('now', '-{} hours') GROUP BY sentiment """.format(hours)) ``` ```python cursor = conn.execute(""" SELECT source, COUNT(*) as count, AVG(relevance_score) as avg_relevance FROM articles WHERE fetched_at >= datetime('now', '-{} hours') GROUP BY source ORDER BY count DESC LIMIT ? """.format(hours), (limit,)) ``` ```python cursor = conn.execute(""" SELECT title, summary FROM articles WHERE fetched_at >= datetime('now', '-{} hours') """.format(hours)) ``` `x_monitor.py` contains an equivalent pattern: ```python query = """ SELECT handle, AVG(likes) as avg_likes, AVG(retweets) as avg_retweets, AVG(views) as avg_views, COUNT(DISTINCT id) as tweet_count FROM tweets WHERE fetched_at >= datetime('now', '-{} days') {} GROUP BY handle """.format(days, "AND handle = ?" if handle else "") params = [handle] if handle else [] cursor = conn.execute(query, params) ``` ### Technical Analysis The `hours` and `days` values are inserted directly into SQL statements using `str.format()`. Python type annotations and default integer v ...[truncated 2007 chars]
Remediation
View remediation
= datetime('now', ?) ORDER BY relevance_score DESC, published DESC LIMIT ? """, (modifier, limit), ) ``` Apply the equivalent pattern to day-based queries: ```python days = validated_window(days, minimum=1, maximum=365) modifier = f"-{days} days" cursor = conn.execute( """ SELECT handle, AVG(likes) AS avg_likes, AVG(retweets) AS avg_retweets, AVG(views) AS avg_views, COUNT(DISTINCT id) AS tweet_count FROM tweets WHERE fetched_at >= datetime('now', ?) GROUP BY handle """, (modifier,), ) ``` Where an optional handle filter is required, use two fixed query templates rather than interpolating arbitrary fragments. Also validate `limit` as a bounded positive integer to prevent resource-exhaustion queries. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
daily_signals.py:294
Finding

Hard-Coded Access to a Host-Level OpenClaw Memory Directory

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This mismatch is especially concerning because it suggests undeclared scraping capability while omitting several declared ingestion and reporting components. Undeclared collection from an unexpected source materially increases risk: users may not realize what third-party sites are contacted, what data is collected, or whether the skill violates policy or terms of service.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

This mismatch is especially concerning because it suggests undeclared scraping capability while omitting several declared ingestion and reporting components. Undeclared collection from an unexpected source materially increases risk: users may not realize what third-party sites are contacted, what data is collected, or whether the skill violates policy or terms of service.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

This mismatch is especially concerning because it suggests undeclared scraping capability while omitting several declared ingestion and reporting components. Undeclared collection from an unexpected source materially increases risk: users may not realize what third-party sites are contacted, what data is collected, or whether the skill violates policy or terms of service.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

This is a true tool-parameter abuse issue because untrusted or future-variable input is interpolated directly into a shell command controlling the gog CLI. In the context of a pipeline that pulls Gmail newsletters, exploitation could let an attacker alter the search, execute arbitrary commands, or abuse the Gmail-accessing tool to retrieve unintended mailbox data.

Content

Scanner excerpt · newsletter_monitor.py (reported line 25)May include surrounding context.

python
def run_gog(query):
    """Run gog command and return JSON"""
    try:
        result = subprocess.run(
            f"gog gmail search '{query} newer_than:30d' --max 5 --json",
            shell=True,
            capture_output=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly instructs users to configure Gmail access and documents persistent local storage of collected data, but it provides no privacy, retention, or credential-handling guidance. In a pipeline that aggregates newsletters and social content, this omission can lead to overcollection, unsafe storage of potentially sensitive email-derived content, and accidental exposure of local databases or generated reports.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises and instructs use of code that performs network access, local file/database writes, and shell-command execution, but the manifest declares no explicit tool scope or permissions boundaries. This is dangerous because an agent or user may run a broadly capable skill without clear consent or least-privilege constraints, increasing the chance of unintended data access or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs use of Gmail newsletter search/access but does not warn users that mailbox content may be accessed, parsed, and potentially retained or transformed. Access to email content is sensitive, and without prominent disclosure users may expose private or regulated information beyond what they intended.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation presents this as a simple daily task to find one signal and draft a post, but the implementation also initializes storage and performs weekly/monthly historical compilation. That mismatch can mislead reviewers and users about the true behavior and privileges of the script, reducing informed consent and making sensitive data accumulation harder to detect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file persists derived signal data and generated drafts to a local path under the user's workspace, expanding the data lifecycle beyond transient signal gathering. Because the content originates from external feeds and may include sensitive or proprietary material, silent persistence increases privacy, retention, and unintended disclosure risk, especially when paired with later aggregation and database storage.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code introduces access to Gmail newsletter content, which is a sensitive mailbox source, despite the module's stated purpose being daily signal gathering and post drafting. Mailbox access materially increases privilege and privacy exposure, and if the newsletter monitor is broad or misconfigured it could ingest non-newsletter email content or metadata without meaningful user awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The newsletter feature accesses Gmail-derived data without any user-facing warning, disclosure, or confirmation at the point of use. Silent access to mailbox content is dangerous because users may not realize the script is reading email data, and that undermines consent and increases the chance of over-collection from a highly sensitive source.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code builds a shell command with an f-string and executes it with shell=True, which enables command injection if the query string ever contains shell metacharacters or quotes. Although the current NEWSLETTERS list is hardcoded, run_gog() is a reusable helper and the unsafe pattern is still present; in a skill that accesses Gmail data, command injection could lead to arbitrary local command execution and exposure of mailbox contents or other host data.

Content

Scanner excerpt · newsletter_monitor.py (reported line 25)May include surrounding context.

python
def run_gog(query):
    """Run gog command and return JSON"""
    try:
        result = subprocess.run(
            f"gog gmail search '{query} newer_than:30d' --max 5 --json",
            shell=True,
            capture_output=True,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file is documented and structured as a Telegram channel monitor, but it also implements a separate search_wechat capability that queries Sogou for WeChat articles. While the overall skill manifest mentions RSS, X/Twitter, Telegram, and Gmail newsletters, WeChat is not part of the stated sources, so this code goes beyond the declared behavior for this component and the skill description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code performs outbound network requests to a third-party service and persists fetched content into a local SQLite database automatically, without any consent prompt, configuration gate, or visible disclosure at the point of use. In a content-intelligence skill, this is not inherently malicious, but it creates privacy and operational risk because running the module causes data transmission and durable storage that a user may not expect.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
79% confidence
Finding

The module sends tweet-derived identifiers to api.fxtwitter.com, a third-party endpoint outside the primary platform, which exposes usage patterns and requested content to an external service. In this skill context, external transmission is expected for functionality, but the risk remains because the dependency is implicit, not user-approved, and relies on a non-official intermediary that may log requests or change behavior unexpectedly.

Content

Scanner excerpt · x_monitor.py (reported line 209)May include surrounding context.

python
handle = parts[-2] if len(parts) >= 2 else ""
        tweet_id = parts[-1] if parts else ""
        
        api_url = f"https://api.fxtwitter.com/{handle}/status/{tweet_id}"
        req = urllib.request.Request(api_url, headers={"User-Agent": "Mozilla/5.0"})
        
        with urllib.request.urlopen(req, timeout=15) as resp:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill states that collected content is stored in multiple SQLite databases but does not clearly warn users about persistent local retention of third-party and potentially sensitive content. Even if local-only, undocumented persistence increases privacy, compliance, and data-minimization risk because users may assume the pipeline is ephemeral.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code writes daily signals and generated drafts to disk without notifying the user that collected content will be retained locally. While local persistence is not inherently malicious, undisclosed storage creates avoidable privacy and operational risk, particularly if the workspace is synced, shared, or backed up.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens reproducibility and makes it impossible to verify whether the environment is using a version affected by known advisories in feedparser.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
# Signal Pipeline Dependencies
feedparser>=6.0.0
beautifulsoup4>=4.12.0
requests>=2.31.0
httpx>=0.25.0

Unverifiable Dependency: feedparser has 10 known advisory(ies) (CVE-2011-1157 (feedparser Cross-site Scripting vulnerability); CVE-2009-5065 (feedparser Cross-site Scripting vulnerability); CVE-2011-1158 (feedparser Cross-site Scripting vulnerability) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

feedparser has known advisories, but the manifest does not pin a version, so there is no reliable way to determine whether deployment will use an affected release. In a pipeline that ingests external RSS content, uncertainty around parser version increases the risk of exposing downstream components to known parsing or content-handling flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

Using an unpinned beautifulsoup4 dependency permits non-deterministic installs, which can unexpectedly introduce vulnerable or breaking releases. Even without a currently cited advisory here, the lack of exact pinning increases supply-chain risk and reduces auditability.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
# Signal Pipeline Dependencies
feedparser>=6.0.0
beautifulsoup4>=4.12.0
requests>=2.31.0
httpx>=0.25.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The unpinned requests dependency allows the installed version to vary by environment and time, making security posture uncertain. This is more concerning because requests has multiple historical advisories, so not pinning prevents clear assurance that a safe version is used.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
# Signal Pipeline Dependencies
feedparser>=6.0.0
beautifulsoup4>=4.12.0
requests>=2.31.0
httpx>=0.25.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

requests has multiple known advisories, and without an exact version pin the installed package may be vulnerable depending on when and where installation occurs. Because this skill is intended to fetch data from external services, using an unverifiable HTTP client version increases the chance of credential leakage or request-handling issues tied to known CVEs.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Specifying httpx with only a minimum version allows dependency resolution to drift, which can pull in unexpected releases and complicate vulnerability management. This creates avoidable supply-chain uncertainty, especially for a network-facing library.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
feedparser>=6.0.0
beautifulsoup4>=4.12.0
requests>=2.31.0
httpx>=0.25.0

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

httpx has known advisories, and the absence of version pinning means the security status of the installed dependency cannot be verified. Since the skill’s purpose involves collecting signals over the network, uncertainty in a core HTTP library meaningfully increases supply-chain and runtime risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module calls init_db() at import time, which automatically creates or opens a persistent local SQLite database file as a side effect. In an agent skill context, import-time persistence can surprise operators, write data without explicit consent, and retain potentially sensitive feed/article content from RSS, Gmail newsletters, or other marketing sources.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.