Back to skill

Security audit

Twitter Watch Reply

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for semi-automated Twitter/X monitoring and draft replies, but one helper can execute a spoofed local script and the workflow relies on sensitive account/session access.

Review before installing. Use a scoped 6551 token, run commands only from a trusted workspace, keep the semi-automatic confirmation step for any public reply, and avoid or patch render_alert_text.py until it resolves render_alert.py relative to its own installed directory. Enable notifications only for channels and targets you control.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (1)

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/render_alert_text.py:9
Finding

Relative Subprocess Path Can Execute an Attacker-Controlled Script

Content
View full analysis

Vulnerability Details

File Location: scripts/render_alert_text.py, lines 9–11
Vulnerability Type: Tool hijacking through unsafe relative-path resolution
Risk Level: Medium

Vulnerable Code

python
import subprocess
raw = subprocess.check_output(
    ['python3', 'skills/twitter-watch-reply/scripts/render_alert.py'],
    text=True
)

Technical Analysis

The subprocess target is specified as a path relative to the process's current working directory. It is not resolved relative to the trusted, installed location of render_alert_text.py.

Consequently, the invoked file can differ from the audited scripts/render_alert.py. If execution starts in a directory containing an attacker-controlled file at skills/twitter-watch-reply/scripts/render_alert.py, Python will execute that file instead.

No shell is used, so this is not shell-command injection. The weakness is executable-script path spoofing: the current working directory implicitly determines which Python source file receives execution privileges.

Attack Path

  1. An attacker gains permission to create files in a directory from which the user or Agent may invoke render_alert_text.py.
  2. The attacker creates: skills/twitter-watch-reply/scripts/render_alert.py
  3. The attacker places arbitrary Python code in that spoofed file.
  4. The user or Agent runs the legitimate render_alert_text.py while the attacker-controlled directory is the current working directory.
  5. subprocess.check_output() starts python3 with the relative path.
  6. Python executes the spoofed script with the privileges and environment of the user or Agent.

This path requires the attacker to influence the working directory or its contents. It does not provide an unauthenticated remote attack by itself.

Impact Assessment

Successful exploitation permits arbitrary Python code execution with the invoking process's privileges. The malicious script could read accessible files and environment variabl ...[truncated 283 chars]

Remediation
View remediation

Remediation Suggestions

Prefer eliminating the subprocess and invoking trusted Python functions directly. Refactor alert construction into a shared function imported by both renderers.

If process isolation is required, resolve the target from the current script's trusted location and use the active Python interpreter:

python
from pathlib import Path
import subprocess
import sys

script_path = Path(__file__).resolve().parent / 'render_alert.py'
raw = subprocess.check_output(
    [sys.executable, str(script_path)],
    text=True
)

Additional hardening should include:

  • Verify that script_path is a regular file beneath the expected Skill directory.
  • Avoid depending on the caller's current working directory.
  • Use sys.executable rather than a PATH-resolved python3 executable.
  • Run the Skill with a minimal environment and only the filesystem permissions needed for its data directory.
  • Add a regression test that invokes render_alert_text.py from an unrelated directory containing a spoofed relative script and verifies that only the installed script can execute.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The README's sample config sets "language": "zh", which establishes a specific output language by default. Under the policy, forcing a language without opt-in or justification can be a natural-language locale policy violation, and this README does not explain that the skill is intended only for a Chinese-language use case.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requests or implies broad capabilities (environment access, file read/write, network, and shell) but does not declare any explicit tool scope or permission boundaries. In a skill that fetches remote content, reads secrets from environment variables, writes persistent state, and can drive follow-on actions, missing scope declarations increases the chance of over-privileged execution, accidental secret exposure, or unsafe command/network use by the host agent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill metadata description is written entirely in Chinese and the rest of the document also assumes Chinese as the operating language, but there is no opt-in, alternative locale, or documented reason for restricting the skill to that language. This can violate language/locale policy when users are not explicitly given 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

This manifest file sets the language to "zh" as a fixed value, which imposes a specific language/locale behavior. Under the policy rules, forcing a language without user opt-in or clear documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The document content is presented in Chinese and immediately defines the skill behavior in that language, without offering an alternative language option or documenting a justified locale constraint. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file instructs the skill to generate '3 条中文回复候选' and defines default response styles in Chinese, which imposes a specific language behavior. Under the policy, language constraints should be user-selectable or clearly justified; neither is present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The connectivity check sends the TWITTER_TOKEN as a bearer token to an external service endpoint, but the script provides no explicit user-facing notice at runtime that invoking the health check will perform an authenticated outbound request. In a diagnostic utility, this can surprise operators, leak operational metadata to the third party, and normalize token transmission in environments where users may expect only local validation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The helper sends POST requests to external endpoints and includes a bearer token in the Authorization header, but there is no confirmation prompt, user-facing log, or explanatory comment/docstring warning that account-related data and credentials are being transmitted. This is a code file, so external network calls that transmit user or system data should include some visible disclosure unless clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The candidate messages are always generated in Chinese string literals, with no configuration or user choice for language. This is a natural-language policy concern because the skill imposes a locale-specific response format without any visible opt-in or documented region-specific constraint.

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/render_alert_text.py (reported line 11)May include surrounding context.

python
def main():
    cfg = load_json(CONFIG_PATH, {})
    import subprocess
    raw = subprocess.check_output(['python3', 'skills/twitter-watch-reply/scripts/render_alert.py'], text=True)
    data = json.loads(raw)
    alert = data.get('alert')
    if not alert:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This is a markdown file, so missing-warning review applies to documented behaviors. The instructions explicitly direct the skill to read tweet data and use it for reply generation, but there is no warning about handling external content or potential privacy considerations in the description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script updates and saves pending tweet state to STATE_PATH, which is a file write affecting local data, but the code provides no confirmation prompt, no explanatory comment/docstring, and no user-facing message indicating that local state will be modified. For code files, file writes should have some form of disclosure when not otherwise documented.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This Python file invokes another script via subprocess.check_output, which is a safety-relevant operation under the code-file warning criteria. The file provides no confirmation prompt, comment, docstring, or user-facing log explaining that it will execute an external script before doing so.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.