Back to skill

Security audit

Twitter Listen Comment

Security checks for vulnerabilities and agentic risk

Overview

This skill is not plainly malicious, but it needs review because it can automatically post public X replies from a logged-in browser session using model-generated content.

Review carefully before installing or running. Use only with accounts you are willing to let this automation publicly reply from, prefer a dedicated Chrome profile with no unrelated logged-in sessions, protect the token, disable or limit notifications if tweet activity is sensitive, and add manual approval or dry-run behavior before allowing posts.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T01 · Skill Instruction Hijacking

Error
Location
scripts/twitter_listen_comment.py:91
Finding

Untrusted Tweet Content Can Influence a Browser-Enabled Agent

Content
View full analysis

Vulnerability Details

File Location: scripts/twitter_listen_comment.py:91-124, with the second-stage browser invocation at scripts/twitter_listen_comment.py:147-178
Vulnerability Type: Indirect prompt injection through externally controlled tweet content
Risk Level: High

Vulnerable Code

Tweet text received from the external API is retained without validation:

python
return {
    'id': tweet_id,
    'text': latest.get('text', ''),
    'createdAt': latest.get('createdAt', ''),
    'url': f'https://x.com/{username}/status/{tweet_id}',
    'userScreenName': latest.get('userScreenName', username),
    'favoriteCount': latest.get('favoriteCount', 0),
    'replyCount': latest.get('replyCount', 0),
    'retweetCount': latest.get('retweetCount', 0),
}

The untrusted text is interpolated directly into the reply-generation prompt:

python
f'Author: @{tweet.get("userScreenName", "")}\n'
f'Tweet URL: {tweet.get("url", "")}\n'
f'Tweet content: {tweet.get("text", "")}'

The resulting prompt is passed to an Agent:

python
res = run([
    OPENCLAW_BIN,
    'agent',
    '--to',
    agent_target,
    '--message',
    build_reply_prompt(tweet, style),
    '--json'
])

The generated reply is subsequently embedded in a second prompt and sent to an Agent authorized to use the authenticated browser:

python
f'Tweet URL: {tweet.get("url", "")}\n'
f'Reply content: {reply_text}'
python
res = run([
    OPENCLAW_BIN,
    'agent',
    '--to',
    agent_target,
    '--message',
    build_post_prompt(tweet, reply_text),
    '--json',
    '--timeout',
    '180'
])

Technical Analysis

Tweet text is externally controlled by any monitored X account. The implementation places that content directly into a natural-language Agent prompt without a structured trust boundary, escaping, instruction-neutral encoding, or an explicit ...[truncated 3015 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace natural-language browser delegation with deterministic automation

    • Pass only a validated X status URL and a validated plain-text reply to a narrowly scoped browser routine.
    • Do not ask a general-purpose Agent to interpret generated content while it has browser capabilities.
  2. Create an explicit trust boundary

    • Represent tweet content and generated replies as structured data fields rather than concatenating them into instructions.
    • If an Agent must be used, clearly delimit untrusted fields and state that their contents must never be treated as commands.
    • Use separate trusted instruction and untrusted data channels where supported.
  3. Validate generated replies before browser use

    • Enforce a conservative maximum character count.
    • Reject URLs, markup, tool names, browser directives, role markers, encoded payloads, and command-like language.
    • Reject control characters and unexpected line structures.
    • Require human confirmation when validation fails or content appears instruction-like.
  4. Constrain browser capabilities

    • Allowlist only https://x.com/ and the exact expected status URL.
    • Limit the browser workflow to opening the specified tweet, entering text into the reply field, and submitting it.
    • Prevent navigation to unrelated origins and deny unrelated account actions.
    • Use a dedicated browser profile containing no unrelated authenticated sessions.
  5. Add independent postcondition verification

    • Do not rely solely on Agent-generated JSON claiming status: submitted.
    • Verify that the browser remained on the expected X origin and status page.
    • Confirm that the submitted reply appears under the intended tweet and matches the validated reply text.
  6. Reduce automation risk

    • Add an optional approval step before publication, particularly for newly monitored accounts.
    • Rate-limit replies ...[truncated 181 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (14)

Tainted flow: 'req' from os.getenv (line 66, 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/twitter_listen_comment.py (reported line 72)May include surrounding context.

python
headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'},
        method='POST',
    )
    with urllib.request.urlopen(req, timeout=20) as resp:
        return json.loads(resp.read().decode('utf-8'))

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The reply-generation prompt directly concatenates untrusted tweet text into instructions for another agent without clear data/instruction separation or defensive prompting. A malicious tweet can contain prompt-injection content that manipulates the downstream model into producing harmful, policy-violating, or attacker-desired output, which this script may then publish automatically.

Content

No source excerpt is available for this finding.

Ssd 4

High
Category
Not specified by scanner
Confidence
92% confidence
Finding

The posting prompt gives the agent a step-by-step narrative to open a tweet and interact with the browser, while the tweet URL and generated reply are inserted as trusted inputs. Because the upstream reply generation also consumes untrusted tweet text, a malicious tweet can indirectly shape the later browser task through gradual context transfer rather than explicit jailbreak keywords, creating a semantic prompt-injection path that culminates in real-world actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script automatically generates and submits public replies on X whenever a fresh tweet is detected, with no human approval gate, dry-run mode, or explicit per-post confirmation. In this skill context, that is dangerous because unreviewed LLM-generated content can be published from a real account, causing reputational harm, spam/abuse, or policy violations at scale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README states that the skill monitors Twitter/X, generates replies, and uses browser automation to post comments, but it does not prominently warn users that it will automatically publish public content on their behalf. In an automation skill, missing this disclosure is dangerous because users may run it without fully understanding that it can create visible, attributable actions from their logged-in account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README mentions sending tweet-detection and comment-success notifications to external channels such as Telegram, but it does not warn that tweet metadata, links, account activity, and automation status may be transmitted to third-party services. This creates a privacy and data-handling risk, especially if users assume monitoring and posting remain local.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description advertises automated monitoring and commenting on X but does not clearly warn the user that it will post public replies from their already logged-in account. In this context, the omission is dangerous because the workflow is explicitly designed for autonomous generation and browser-driven submission of comments, creating a significant risk of unintended public posting, reputational harm, and account misuse if the user does not fully understand the behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The configuration hard-codes the reply language to "zh", which imposes a specific language/locale behavior with no indication of user opt-in or contextual justification. This matches the policy concern for natural-language locale constraints that are enforced without offering a choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The configuration hard-codes replyStyle.language to "zh", which imposes a specific language on all outputs. For this file type, natural-language policy violations apply, and there is no indication here of user opt-in, language selection, or a documented region-specific justification.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/twitter_listen_comment.py (reported line 59)May include surrounding context.

python
def run(cmd):
    return subprocess.run(cmd, text=True, capture_output=True)


def api_post(url: str, payload: dict):

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The natural-language prompt explicitly instructs the agent to generate a Chinese humorous reply, imposing a specific language choice. A second prompt then uses Chinese instructions for posting, with no indication that the user can choose language or that the skill is intentionally restricted to a Chinese-only context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example configuration sets replyStyle.language to "zh", which signals a fixed language choice in the skill's natural-language behavior. The README does not present this as optional user choice or explain a region-specific requirement, so it may violate the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The requirements instruct users to export a TWITTER_TOKEN but do not warn about the sensitivity of that credential or safe handling practices. Because this skill combines token-based tweet monitoring with automated posting behavior, poor credential hygiene could expose account data or enable unauthorized use if the token is logged, stored insecurely, or shared in shell history.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This manifest-style JSON specifies source users and notification targets, but it does not document any explicit activation boundaries, exclusion conditions, or negative examples for when monitoring and downstream actions should or should not occur. In a manifest/config context, the absence of trigger-scope clarification can make invocation behavior ambiguous, especially as the file appears to define who is watched and where actions are sent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.