Back to skill

Security audit

X Twitter Poster

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed X posting automation, but it requires broad access to a logged-in Chrome session and includes extra tweet-reading capability beyond simple posting.

Review before installing. Use only with a dedicated Chrome profile or disposable account, keep the CDP port bound to localhost, close the debugging-enabled browser immediately after use, and do not use this with your main browser session. Pin dependencies and add a lockfile before trusting it in a real account workflow.

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

T08 · Insecure Dependencies

Warning
Location
package.json:6
Finding
Unpinned Third-Party Dependency and Missing Lockfile## Vulnerability Details **File Location**: `package.json:6-8` **Vulnerability Type**: Supply-chain dependency risk **Risk Level**: Medium ### Vulnerable Code ```json "dependencies": { "playwright": "^1.40.0" } ``` The installation documentation invokes dependency resolution without a committed lockfile: ```bash npm install ``` This instruction appears in `README.md:37-41` and is also referenced in `SKILL.md:308`. ### Technical Analysis The caret version constraint permits npm to install Playwright releases newer than the version originally reviewed, provided they remain compatible with the declared semantic-version range. The project does not include a `package-lock.json`, so dependency resolution is not reproducible and transitive dependency versions are not integrity-pinned. This is particularly relevant because Playwright executes with the privileges of the local Node.js process and is deliberately connected to an authenticated Chrome instance through CDP. A malicious or compromised dependency release could therefore execute local code during installation or runtime and potentially interact with the browser session. No malicious Playwright package or currently exploited dependency was identified in the reviewed project. The vulnerability is the absence of controls ensuring that users install the same reviewed dependency graph. ### Attack Path 1. An attacker compromises a package release, maintainer account, registry distribution channel, or permitted transitive dependency. 2. The compromised release falls within the version range allowed by `^1.40.0`. 3. A user follows the documented instruction and runs `npm install`. 4. npm resolves and installs the compromised release because no committed lockfile constrains the dependency graph. 5. Malicious dependency code executes through an installation lifecycle hook or when the Skill imports and invokes Playwright. 6. The code inherits the Node.js proces ...[truncated 829 chars]
Remediation
## Remediation Suggestions 1. Replace the version range with an exact, reviewed Playwright version: ```json "dependencies": { "playwright": "1.40.0" } ``` 2. Generate and commit `package-lock.json` so direct and transitive dependency versions and integrity hashes are recorded. 3. In deployment and documented workflows, replace `npm install` with `npm ci` to enforce the committed lockfile. 4. Review dependency and lockfile changes before approving upgrades. 5. Use automated dependency vulnerability scanning and monitor Playwright security advisories. 6. Consider disabling npm lifecycle scripts during installation where compatible: ```bash npm ci --ignore-scripts ``` 7. Install and run the Skill in an isolated environment with a dedicated Chrome profile, as already recommended by the project documentation. 8. Keep the CDP endpoint bound to localhost, expose it only while required, and close the debugging-enabled browser immediately after use.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The entire skill documentation, warnings, setup steps, and usage examples are presented only in Chinese. Under the stated policy, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy violation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill documents use of environment variables such as CDP_URL and X_USERNAME but does not declare any explicit tool scope or permission boundaries. In practice this weakens reviewability and containment, because a skill that can access local browser debugging endpoints and environment-derived configuration has meaningful execution capability without a clearly declared trust boundary.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are very broad and map to common natural-language requests like '发推' or '帮我发一条关于 XX 的推', increasing the chance the skill auto-activates in situations where the user did not intend a high-risk browser automation flow. Because activation can lead to use of a powerful CDP-connected browser session, accidental invocation materially raises security risk.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The skill claims a narrow purpose of posting to X, but its documented mechanism is a CDP connection to the user's live Chrome session, which grants access to all tabs plus cookie and session read/write. That creates a much broader authority surface than the user-facing description suggests, enabling account takeover, cross-site data theft, or actions on unrelated sites if the skill or its dependencies are modified or abused.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The example explicitly inspects an existing page from the user's current browser context to verify and log the current URL. Accessing arbitrary pre-existing tabs is broader than necessary to compose a tweet and exposes unrelated browsing activity, potentially including sensitive application state or personal data visible in open tabs.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill is presented as a tweet-posting tool, but it also includes a function to navigate to a user's profile and extract recent tweet text via the user's authenticated browser session. This expands the capability from write-only automation into authenticated data access, which violates least privilege and creates undisclosed privacy/exfiltration risk if the function is invoked directly or later wired into the agent.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The code contains content-extraction logic that scrapes tweet text from x.com using selectors inside page.evaluate, which is unrelated to simply composing and sending a tweet. In the context of a skill that connects over CDP to a logged-in browser, hidden read capabilities are especially dangerous because they can access account-visible content under the user's session without transparent disclosure.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The entire skill description and usage guidance are written as Chinese-only instructions, and the skill does not state that users may choose another language or locale. Under the policy, a language constraint should either be optional for the user or clearly documented as a justified region-specific limitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"description": "X/Twitter posting skill using Playwright",
  "main": "post_tweet.js",
  "dependencies": {
    "playwright": "^1.40.0"
  },
  "author": "",
  "license": "MIT"
Confidence
91% confidence
Finding
The dependency is specified with a caret range (^1.40.0), which permits automatic installation of newer minor/patch releases rather than a strictly reviewed version. In a skill that automates a logged-in browser session via Playwright, this weakens supply-chain control and can unexpectedly introduce vulnerable or behavior-changing code.

Unverifiable Dependency: playwright has 1 known advisory(ies) (CVE-2025-59288 (Playwright downloads and installs browsers without verifying the authenticity of)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding
The manifest references Playwright without an exact pinned version, while Playwright has at least one known advisory involving browser downloads without authenticity verification. Because this skill uses Playwright in a high-trust context with access to the user's already logged-in browser via CDP, uncertainty about the installed version increases the chance of pulling an affected release and amplifies supply-chain risk.

Static analysis

No suspicious patterns detected.