Back to skill

Security audit

Article Publisher

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it can publish publicly across logged-in accounts and stores reusable login cookies locally with weak protection.

Review carefully before installing. Use this only for accounts where automated publishing is acceptable, prefer testMode first, confirm every target platform manually before live publishing, and avoid using publish_to_all for sensitive or brand accounts. Treat data/cookies as bearer credentials: keep the working directory private, do not sync or commit it, and clear cookies with logout when done. Prefer official registries/download sources and pinned dependency installs instead of the mirror/npx guidance where possible.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/lib/cookie-manager.ts:19
Finding
Authentication Cookies Are Stored in Plaintext Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `src/lib/cookie-manager.ts:19-32`; related directory configuration in `src/lib/config.ts:16-21, 45-48` **Vulnerability Type**: Plaintext storage of sensitive session credentials with unsafe default permissions **Risk Level**: High ### Vulnerable Code ```ts // src/lib/cookie-manager.ts:19-32 async saveCookies(cookies: CookieData['cookies']): Promise<void> { ensureCookieDir(); const config = getConfig(); const now = new Date(); const expiresAt = new Date(now.getTime() + config.cookieExpiryDays * 24 * 60 * 60 * 1000); const cookieData: CookieData = { cookies, createdAt: now.toISOString(), expiresAt: expiresAt.toISOString(), }; const cookiePath = getCookiePath(this.platform); fs.writeFileSync(cookiePath, JSON.stringify(cookieData, null, 2), 'utf-8'); } ``` ```ts // src/lib/config.ts:16-21 const defaultConfig: Config = { cookieDir: path.join(process.cwd(), 'data', 'cookies'), cookieExpiryDays: 30, headless: false, timeout: 60000, slowMo: 100, }; ``` ```ts // src/lib/config.ts:45-48 export function ensureCookieDir(): string { const config = getConfig(); if (!fs.existsSync(config.cookieDir)) { fs.mkdirSync(config.cookieDir, { recursive: true }); } ``` ### Technical Analysis The application persists complete Playwright session cookies as unencrypted, human-readable JSON. These cookies may contain bearer credentials that allow an authenticated browser session to be reconstructed without knowing the user's password or repeating QR-code authentication. Neither `mkdirSync` nor `writeFileSync` specifies a restrictive permission mode. Effective permissions therefore depend on the process umask. On common Unix-like configurations, the directory may be created as `0755` and the cookie files as `0644`, potentially allowing other local users to discover and read the stored credentials. The cookie directory is also based on `process.cwd()`. If the application is launc ...[truncated 1759 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the credential directory with owner-only permissions: ```ts fs.mkdirSync(config.cookieDir, { recursive: true, mode: 0o700, }); fs.chmodSync(config.cookieDir, 0o700); ``` 2. Write cookie files with mode `0600` and avoid following attacker-controlled symbolic links. Use an exclusive or atomic write process where appropriate: ```ts fs.writeFileSync(cookiePath, JSON.stringify(cookieData), { encoding: 'utf-8', mode: 0o600, flag: 'w', }); fs.chmodSync(cookiePath, 0o600); ``` 3. Store credentials in a per-user application data directory rather than under `process.cwd()`. Ensure the location is outside repositories, shared directories, and cloud-synchronized folders. 4. Prefer an operating-system credential store such as Keychain, Credential Manager, or Secret Service. If file storage is unavoidable, encrypt cookie data using a key protected by the operating system rather than storing the encryption key beside the data. 5. Validate the resolved cookie path, reject symbolic links, and ensure the final path remains inside the intended credential directory before reading, writing, or deleting it. 6. Minimize retention time and store only cookies required for the authenticated workflow. Do not assume the locally recorded 30-day expiration matches the platform's real cookie expiration. 7. Add `data/cookies/` and test screenshots to `.gitignore`, backup exclusions, and packaging exclusions. 8. On logout, invalidate the server-side session where supported instead of only deleting the local file. Securely revoke all associated authentication tokens. 9. Document that cookie files are bearer credentials and must not be copied, committed, logged, shared, or attached to support requests. ]]>

T08 · Insecure Dependencies

Warning
Location
package.json:8
Finding
Installation Guidance Uses Third-Party Mirrors Without Project-Level Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `package.json:8-11`; `src/lib/auto-install.ts:82-95`; `src/index.ts:34-39` **Vulnerability Type**: Software supply-chain exposure through non-default dependency and browser binary sources **Risk Level**: Medium ### Vulnerable Code ```json // package.json:8-11 "scripts": { "install:browser": "npx playwright install chromium", "install:browser:cn": "cross-env PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium" }, ``` ```ts // src/lib/auto-install.ts:82-95 if (!hasDeps) { instructions.push('npm dependencies not found. Please run:'); instructions.push(' cd ' + join(__dirname, '..')); instructions.push(' npm install --registry=https://registry.npmmirror.com'); } if (!hasBrowser) { instructions.push('Playwright browser not found. Please run:'); instructions.push(' npm run install:browser:cn'); instructions.push('or:'); instructions.push(' npx playwright install chromium'); } ``` ```ts // src/index.ts:34-39 } catch (error) { return { result: `Environment check failed: ${error instanceof Error ? error.message : String(error)} Please manually run the following commands to install dependencies: 1. npm install --registry=https://registry.npmmirror.com 2. npm run install:browser:cn`, data: { ready: false } }; } ``` The source file's original user-facing strings are in Chinese; the above presentation translates them into English without changing the commands under review. ### Technical Analysis The generated setup instructions recommend downloading npm dependencies and a Playwright Chromium binary through `npmmirror.com`, a source outside the default npm registry and Playwright distribution path. The audited repository contains no lockfile, so the declared ranges such as `playwright: "^1.40.0"` do not establish a reproducible dependency graph at project level. The setup guidance also does not require explicit checksum or signatur ...[truncated 1996 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make the official npm registry and Playwright browser distribution source the default installation path. 2. Treat third-party mirrors as explicit, opt-in alternatives. Clearly explain that selecting a mirror changes the software supply-chain trust boundary. 3. Commit a reviewed `package-lock.json` and use reproducible installation commands: ```bash npm ci ``` 4. Pin security-sensitive dependencies to reviewed exact versions instead of broad version ranges where operationally practical. 5. Configure CI to reject unapproved registry URLs and unexpected lockfile changes. 6. Verify downloaded browser artifacts using trusted checksums or signatures obtained independently from the distribution channel. Do not rely solely on transport encryption from the same source that supplies the artifact. 7. Avoid invoking an implicitly downloaded executable through an unpinned `npx` resolution. Prefer the locally locked Playwright CLI: ```bash npm exec --offline playwright install chromium ``` 8. Add dependency provenance and vulnerability scanning to the release process, including review of package lifecycle scripts. 9. Ensure installation is performed under an unprivileged account and in an isolated environment. Never recommend running npm or browser installation commands with administrator or root privileges. 10. Correct the tool descriptions in `src/index.ts`, which currently state that dependencies are installed automatically even though `checkAndInstall` only reports instructions. Accurate descriptions reduce the chance that callers grant unnecessary trust or privileges to the environment-check operation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (27)

Ae1

High
Category
analysis-evasion
Content
- `src/index.ts` - 主入口文件
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrase `帮我发布文章` is broad and can match ordinary conversation without sufficient confirmation of target platform, account, or content scope. In a skill that automates posting across authenticated media accounts using persisted cookies, ambiguous activation can lead to unintended publication, reputational damage, or accidental cross-account actions.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger `一键发布到所有平台` authorizes a broad, high-impact action across multiple logged-in accounts with minimal specificity. Given the skill's context of browser automation plus cookie persistence, accidental or adversarial invocation could mass-post content to all connected platforms, amplifying harm across brands, audiences, and accounts.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
The install script invokes `npx playwright install chromium`, which can resolve and execute a package version at runtime rather than a fully pinned artifact. In a tool that automates browser actions and persists login state, relying on unpinned runtime package resolution increases supply-chain risk and could lead to installation or execution of an unexpected Playwright version.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
This script combines a custom download host (`PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright`) with `npx playwright install chromium`, creating additional supply-chain exposure because browser binaries are fetched from a mirror rather than the default trusted source. In a browser automation skill that handles authentication cookies and QR-code login, a compromised or tampered browser download could expose credentials or session data.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The adapter invokes the publish button automatically in normal mode without any explicit runtime confirmation from the user immediately before the irreversible action. In a multi-platform auto-publishing skill, this increases the chance of accidental or unauthorized publication if upstream inputs, agent behavior, or state handling are wrong, especially because the code also auto-fills content and proceeds after login/cookie reuse.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s comments, log messages, prompts, and status text are written entirely in Chinese, including user-facing instructions such as login and test-mode guidance. This imposes a specific language on users without any opt-in, fallback, or documented justification that the skill is intentionally limited to Chinese-speaking or region-specific use.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The adapter performs a real publication immediately after filling content unless `testMode` is enabled, and there is no explicit runtime confirmation or approval gate right before the live `clickPublish()` action. In an automation tool that posts to external platforms, this creates a meaningful risk of accidental publication of draft, incorrect, or sensitive content if the caller invokes the method unintentionally or with bad inputs.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This code contains user-facing console output in Chinese and continues that pattern throughout the file, effectively forcing a specific language/locale for interaction. The policy allows locale constraints only when opt-in or clearly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The file's comments and user-facing console messages are entirely in Chinese, including operational prompts such as login and publish-flow guidance. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly documented and justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
This TypeScript skill file presents its tool definitions, parameter descriptions, and runtime result messages entirely in Chinese, and also includes locale-specific installation guidance for China mirrors. Under the policy for natural-language violations, forcing a specific language without user opt-in is reportable unless the locale constraint is explicitly justified, which is not done here.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The code persists authenticated browser cookies to disk after login, which creates a reusable session artifact. In a browser automation tool that logs into publishing platforms, stolen or improperly protected cookie files could let another local user or malware hijack the account without re-authentication.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This code persists cookie contents to a local file via writeFileSync, which is a safety-relevant file write involving sensitive authentication data. While comments describe the function internally, there is no user-facing prompt, warning, or disclosure in this file indicating that cookies will be stored on disk.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The manifest description is written only in Chinese ("自媒体文章多平台发布工具"), which can constitute a language/locale policy issue when no opt-in, alternative locale, or justification is provided. Because this is user-facing natural language in a manifest file, it may exclude users who expect neutral or selectable language behavior.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"install:browser:cn": "cross-env PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium"
  },
  "dependencies": {
    "playwright": "^1.40.0"
  },
  "devDependencies": {
    "cross-env": "^7.0.3"
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

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
87% confidence
Finding
The manifest depends on `playwright`, and the analysis notes a known advisory related to browser downloads without authenticity verification, while the version is not pinned tightly enough to determine exposure. In this skill's context, that matters more because the software downloads browser binaries and then uses them for automated login and publishing workflows, potentially exposing accounts, cookies, and published content if the browser supply chain is compromised.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"playwright": "^1.40.0"
  },
  "devDependencies": {
    "cross-env": "^7.0.3"
  },
  "engines": {
    "node": ">=18.0.0"
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The file's comments and user-visible console messages are written exclusively in Chinese, including login and publishing instructions. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly documented and justified.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The natural-language comments and descriptions are written only in Chinese, which can reflect a language-specific constraint without indicating user choice or a justified locale limitation. Under the policy rule, forcing a specific language without opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
Multiple comments and console messages are written only in Chinese, indicating the skill's user-facing output is tied to a specific language. The file does not provide a user opt-in, fallback language, or justification for a Chinese-only locale constraint.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The screenshot method writes a full-page image to the provided path, which may capture sensitive on-screen content and store it on disk. The code performs the write silently, with no visible prompt, warning, or log explaining that data is being saved.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The comment uses Chinese-language labeling ('Cookie管理器'), and similar Chinese-only comments appear throughout the file. Under the stated policy, forcing a specific language without offering choice or documenting a justified locale constraint can be a natural-language policy violation.

Static analysis

No suspicious patterns detected.