Back to skill

Security audit

Social Publisher

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says by publishing to social platforms, but it asks users to store powerful social-media session cookies in plaintext and can post or schedule content without a clear preview or safety boundary.

Review carefully before installing. Use only accounts and content you are comfortable publishing from this tool, prefer test accounts first, protect or avoid long-lived browser cookies, do not commit the config file, and manually preview scheduled or multi-platform posts before relying on it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/social_publisher.py:20
Finding
Reusable Authentication Cookies Stored in Plaintext Configuration## Vulnerability Details **File Location**: `SKILL.md:30-43`; `scripts/social_publisher.py:20, 42-49` **Vulnerability Type**: Plaintext storage of sensitive authentication credentials **Risk Level**: Medium ### Vulnerable Code `SKILL.md:30-43` instructs users to store reusable session cookies directly in a JSON file: ```json { "juejin": { "cookie": "your-juejin-cookie" }, "zhihu": { "cookie": "your-zhihu-cookie" }, "weibo": { "cookie": "your-weibo-cookie" } } ``` `scripts/social_publisher.py:20, 42-49` reads those plaintext credentials without validating file ownership or permissions: ```python CONFIG_FILE = W / "config/social-publisher.json" def load_config() -> dict: """Load configuration.""" if not CONFIG_FILE.exists(): return {} return json.loads(CONFIG_FILE.read_text(encoding="utf-8")) def get_cookie(platform: str) -> Optional[str]: """Get a platform cookie.""" config = load_config() return config.get(platform, {}).get("cookie") ``` ### Technical Analysis The documented configuration model stores long-lived social-media cookies as unencrypted JSON values. These cookies are bearer credentials: possession may be sufficient to perform authenticated actions under the associated account until the session expires or is revoked. The implementation reads the configuration without checking whether the file is owned by the expected user or protected by restrictive permissions. It also places the expected file under the project tree, increasing the chance that it may be copied with the workspace, included in backups, or accidentally committed to source control. Local encryption alone would not fully resolve this issue if the decryption key were stored beside the file. A platform keychain or dedicated secret manager is the preferred control. ### Attack Path 1. A user follows the documentation and saves active Juejin, Zhihu, or ...[truncated 1031 chars]
Remediation
## Remediation Suggestions 1. Store cookies in an operating-system keychain, credential vault, or dedicated secret-management service rather than in the workspace. 2. If file-based storage must be supported, place the file outside the project tree and require permissions equivalent to `0600`. 3. Before reading the file, verify that it is owned by the current user, is a regular file rather than a symbolic link, and is not accessible by group or other users. 4. Add the configuration path to version-control ignore rules and warn users against placing credentials in repositories, shared workspaces, logs, or backups. 5. Prefer narrowly scoped, revocable platform tokens over full browser session cookies where supported. 6. Document credential revocation and rotation procedures. 7. Avoid printing cookies or including request headers in diagnostic logs.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/social_publisher.py:126
Finding
Form-Parameter Injection in Authenticated Weibo Request## Vulnerability Details **File Location**: `scripts/social_publisher.py:126-140` **Vulnerability Type**: Improper encoding of untrusted form data **Risk Level**: Medium ### Vulnerable Code ```python def publish_to_weibo(content: str, cookie: str) -> dict: """Publish to Weibo.""" url = "https://api.weibo.cn/2/statuses/share.json" # Weibo supports short text and images. text = content[:2000] if len(content) > 2000 else content req = urllib.request.Request( url, data=f"content={text}".encode("utf-8"), headers={ "Content-Type": "application/x-www-form-urlencoded", "Cookie": cookie, "User-Agent": "Mozilla/5.0" }, method="POST" ) ``` ### Technical Analysis The request declares an `application/x-www-form-urlencoded` body but constructs that body by directly interpolating article content into the string `content=...`. The content is not percent-encoded. In form encoding, characters such as `&` delimit parameters, while `=` separates parameter names from values. Consequently, article text containing these characters may be parsed as additional form fields rather than as part of the intended `content` value. Percent signs and encoded control sequences may also cause inconsistent interpretation by intermediaries or the destination API. Because the malformed request carries the user's Weibo cookie, any injected parameters are submitted in an authenticated context. The precise effect depends on which additional parameters the Weibo endpoint recognizes and how it handles duplicate or unexpected fields. ### Attack Path 1. An attacker supplies or influences article content that the victim chooses to publish. 2. The content contains form delimiters, such as `&parameter=value`. 3. The script concatenates the text directly into the request body without URL encoding. 4. The Weibo endpoint parses the injected po ...[truncated 759 chars]
Remediation
## Remediation Suggestions Use a standards-compliant form encoder rather than string interpolation: ```python import urllib.parse form_data = urllib.parse.urlencode({"content": text}).encode("utf-8") req = urllib.request.Request( url, data=form_data, headers={ "Content-Type": "application/x-www-form-urlencoded", "Cookie": cookie, "User-Agent": "Mozilla/5.0" }, method="POST" ) ``` In addition: 1. Validate content type and length before encoding. 2. Define an explicit allowlist of request parameters and never derive parameter names from article content. 3. Add tests for ampersands, equals signs, percent signs, Unicode text, line breaks, and already percent-encoded strings. 4. Confirm the platform's documented character limit after encoding and handle API errors without exposing authentication headers. 5. Consider using a maintained HTTP client that provides structured form submission to reduce manual encoding mistakes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The skill promotes one-click and scheduled posting to external social-media services without clearly warning that user-provided content will be automatically transmitted to third-party platforms. This can cause unintended disclosure of sensitive, draft, or internal material, especially when scheduling and multi-platform fan-out reduce opportunities for user review before publication.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill instructs users to store long-lived social-media session cookies in a local configuration file, but provides no warning about the sensitivity of those credentials or the risk of account takeover if the file is exposed. Because these cookies enable posting as the user across multiple platforms, theft or misuse could lead to unauthorized publishing, privacy loss, and compromise of linked accounts.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This Python file includes the top-level description, CLI help context, and runtime user messages entirely in Chinese, which imposes a specific language/locale on users without any opt-in or alternative. The policy for this audit flags natural-language locale constraints when the skill does not offer a language choice or document a justified region-specific limitation.

External Transmission

Medium
Category
Data Exfiltration
Content
def publish_to_weibo(content: str, cookie: str) -> dict:
    """发布到微博"""
    url = "https://api.weibo.cn/2/statuses/share.json"
    # 微博只支持短文本 + 图片
    text = content[:2000] if len(content) > 2000 else content
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.