Back to skill

Security audit

Xiaohongshu Post (Browser Auto)

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Xiaohongshu posting helper, but its browser mode gives an external/model-driven workflow too much access to authenticated page contents and account actions.

Install only if you are comfortable with browser automation acting in a logged-in Xiaohongshu account. Prefer draft-only or API mode where possible; for browser mode, use a local/self-hosted analyzer endpoint, avoid debug capture, use a dedicated browser profile, review before final publishing, and keep sensitive accounts or copied clipboard data out of the session.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/page_analyzer.py:27
Finding

Authenticated Page HTML Is Transmitted to an External LLM with Incomplete Redaction

Content
View full analysis
str: """脱敏:移除 script/style、常见 token 模式,压缩空白。""" html = re.sub(r"]*>[\s\S]*?", "", html, flags=re.IGNORECASE) html = re.sub(r"]*>[\s\S]*?", "", html, flags=re.IGNORECASE) for pat, repl in _TOKEN_PATTERNS: html = pat.sub(repl, html) html = re.sub(r"\s+", " ", html).strip() return html def _get_page_summary(page) -> str: """获取页面内容摘要:URL + 脱敏后的简化 HTML。""" try: url = page.url html = page.content() html = _sanitize_html(html) if len(html) > MAX_HTML_CHARS: html = html[:MAX_HTML_CHARS] + "\n...[已截断]" return f"URL: {url}\n\nHTML(简化):\n{html}" except Exception as e: return f"获取页面失败:{e}" ``` ```python def _call_openai(prompt: str, api_key: str | None, base_url: str | None) -> str | None: """调用 OpenAI 兼容 API。支持百炼、Ollama(本地无需 Key)等。""" if not OpenAI: return None url = ( base_url or os.environ.get("XHS_ANALYZER_BASE_URL") or os.environ.get("OPENAI_BASE_URL") or BAILIAN_BASE_URL ) key = ( api_key or os.environ.get("DASHSCOPE_API_KEY") or os.environ.get("OPENAI_API_KEY") ) if not key and not _is_local_endpoint(url): return None client = OpenAI(api_key=key or "ollama", base_url=url) model_name = os.environ.ge ...[truncated 2855 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/publish_browser.py:181
Finding

Untrusted Webpage Content Can Influence Authenticated Browser Actions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/publish_browser.py:690
Finding

Generic Automatic Confirmation Can Approve Unrelated Dialogs

Content
View full analysis
0 and confirm_btn.is_visible(timeout=2000): confirm_btn.scroll_into_view_if_needed(timeout=2000) page.wait_for_timeout(500) confirm_btn.click(timeout=3000) print(f"✅ 已点击确认:{text}", file=sys.stderr) confirm_clicked = True page.wait_for_timeout(2000) break except: continue ``` ```python # 每 5 秒检查一次是否有新的确认弹窗 if i % 5 == 0 and i > 0: for text in confirm_texts: try: confirm_btn = page.locator(f"text={text}").first if confirm_btn.count() > 0 and confirm_btn.is_visible(timeout=2000): confirm_btn.click(timeout=3000) print(f"✅ 再次点击确认:{text}", file=sys.stderr) page.wait_for_timeout(2000) break except: continue ``` ### Technical Analysis After clicking the publication button, the script searches the entire page for generic labels equivalent to “Confirm,” “OK,” “Got it,” and “Fine.” It selects the first visible match without establishing that: - The element is inside a modal dialog - The dialog is specifically a publication-confirmation dialog - The dialog title and body match an expected publication message - The element is a button rather than unrelated visible text - The action is safe and reversible The same broad search is repeated during the publication polling loop. Consequently, an unexpected warning, consent prompt, account dialog, overwrite confirmation, or maliciously inserted UI element can be accepted ...[truncated 987 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/publish_browser.py:833
Finding

Debug Mode Persists Raw Authenticated HTML and Screenshots in Predictable Paths

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Third-Party Dependencies Are Installed Without Exact Version or Integrity Pinning

Content
View full analysis
=1.40.0 openai>=1.0.0 ``` The documented installation additionally runs: ```bash pip install -r requirements.txt playwright install chromium ``` ### Technical Analysis The dependency declarations use open-ended lower bounds. A future invocation may install any later `playwright` or `openai` release selected by the package resolver, rather than versions reviewed with this project. No lockfile or package hashes are supplied, and the separately downloaded Chromium artifact is not pinned or independently verified in the project. This makes installations non-reproducible and expands the supply-chain trust boundary to future package and browser releases. There is no evidence in the reviewed project that either named package is malicious or typosquatted. The issue is inadequate dependency integrity control, not a confirmed malicious dependency. ### Attack Path 1. A user follows the documented installation instructions. 2. The package resolver selects a future dependency version permitted by the `>=` constraint. 3. That release is compromised, malicious, incompatible, or introduces an exploitable regression. 4. Package code executes during installation or when the browser automation runs. 5. Because the skill handles API keys, authenticated browser profiles, local files, and network traffic, a compromised dependency inherits access to those resources. ### Impact Assessment A compromised dependency would execute with the privileges of the user running the skill. It could potentially access environment variables, API keys, the persistent browser profile, supplied note files and images, and network connectivity. The likelihood is lower than the direct application flaws because exploitation depends on a compromised or unsafe future depe ...[truncated 21 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a posting/publishing helper, but the documented browser mode also extracts full page HTML and sends it to an external LLM for state analysis. This is a materially different and more sensitive behavior because authenticated page content may include tokens, account data, unpublished content, and other sensitive metadata, creating a real risk of data exfiltration beyond the user’s likely expectations.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 137)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 140)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 143)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 146)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

md
| **浏览器自动化** | 个人账号(无 API 权限) | `publish_browser.py` |

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/post.py (reported line 94)May include surrounding context.

python
def get_access_token(app_key: str, app_secret: str) -> str:
    """Get OAuth2 access token (client_credentials)."""
    url = f"{BASE_URL}/api/v1/oauth2/access_token"
    payload = {
        "app_key": app_key,

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/post.py (reported line 122)May include surrounding context.

python
def get_access_token(app_key: str, app_secret: str) -> str:
    """Get OAuth2 access token (client_credentials)."""
    url = f"{BASE_URL}/api/v1/oauth2/access_token"
    payload = {
        "app_key": app_key,

Ssd 1

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file-level design states that after each page load the script fetches page code and lets a model decide the current state and next action dynamically. Because page text and DOM are untrusted and can contain adversarial instructions, this creates classic indirect prompt injection risk where content on the page can steer automation into unsafe clicks, navigation, or submission behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

At these lines the script sends live page state to analyze_page together with the posting goal, and the file header explicitly says page code is retrieved and analyzed after each navigation. On an authenticated creator page this HTML can contain personal account details, drafts, moderation notices, or other sensitive data, which is exfiltrated to an external model service without explicit notice or minimization.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

These lines combine a natural-language objective to create and publish a note with model analysis of the current page. Mixing an action-oriented goal with untrusted page content increases the chance that malicious or unexpected on-page wording can semantically redirect the model toward unintended actions, especially in an authenticated browser session.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

If normal selectors fail, the script falls back to model analysis to locate and click the final publish control, which is a sensitive irreversible action. An attacker controlling page content, a malicious extension, or an unexpected UI variant could influence the model into selecting the wrong element or confirming an unintended action at the moment of submission.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares significant capabilities (environment access, file read/write, and network use) without an explicit tool scope or permissions boundary. That makes it harder for a caller or review system to understand and constrain what the skill may access, increasing the chance of unintended secret exposure, filesystem access, or network egress during use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code collects the current page URL and page HTML, then includes that content in a prompt sent to a configurable OpenAI-compatible endpoint. Even with basic regex redaction, page content can still contain sensitive data such as account information, unpublished content, internal identifiers, or workflow state, and this transfer happens without any user-consent or disclosure mechanism in this file.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The analyzer embeds untrusted page HTML directly into a natural-language prompt and asks the model to decide the next browser action. A malicious page can include prompt-injection text inside HTML that manipulates the model into returning unsafe actions, misclassifying login state, or steering automation to attacker-chosen selectors or URLs; in this skill, that is especially relevant because the model output drives browser behavior for a publishing workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script is hard-wired to a Chinese-platform workflow and emits Chinese-only draft/output strings such as '小红书草稿(复制到 APP 发布)' and Chinese punctuation handling, without offering the user a language choice. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy concern unless clearly documented as a justified region-specific tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code sends the note title, content, and uploaded image files to Xiaohongshu over network requests once credentials are present, but the user-facing CLI flow does not explicitly disclose that their content and local files will be transmitted to a third-party service. Although the script description mentions API posting support, it does not clearly warn at execution time about network transmission of user data and images.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default browser profile directory persists session cookies and account state under ~/.openclaw/xhs-browser without a clear disclosure or consent step. Because this skill automates a personal publishing account, retained authentication material increases the chance of unintended reuse, local compromise, or cross-run posting with an already logged-in identity.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script imports pyautogui and sends OS-level Esc keypresses outside the browser sandbox to close file dialogs. That exceeds normal Playwright page automation and can affect whichever window currently has focus, creating unintended interaction with the host desktop or other applications if focus is stolen or the environment is manipulated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The persistent browser context requests clipboard-read and clipboard-write permissions even though the script's main purpose is posting notes. Elevated clipboard access can expose unrelated sensitive user data copied on the system or let the automation overwrite clipboard contents, and there is no user-facing explanation or scoping of this access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

In debug mode the script writes full page HTML and screenshots to local files under the user's home directory. Those artifacts may include authenticated session content, account information, unpublished notes, and platform responses, creating unnecessary local data exposure if the machine is shared or later compromised.

Content

No source excerpt is available for this finding.

Ssd 4

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script repeatedly observes page content, asks the model what to do next, and progresses toward login, editing, image upload, and publication. Even if each individual step seems low risk, the cumulative multi-step loop increases the chance of gradual prompt steering or deception by untrusted page content, culminating in an authenticated publish action.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest says to use the skill when the user wants to publish, schedule, batch post, generate Xiaohongshu-style content, or automate publishing, which spans both content generation and account actions without clear boundaries. It does not provide exclusion conditions or negative examples to clarify when this skill should not trigger versus a more general writing or social-media drafting skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

Phrases like '把这段内容发到小红书' and '生成小红书文案' are understandable but still broad enough to cover distinct intents such as drafting only, formatting, or actual publishing. The section lists positive examples only and does not distinguish between safe drafting use and actions that should invoke posting automation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.