Back to skill

Security audit

zeelin-x-creator-briefing

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly designed to scrape public X content and publish briefings, but its default and scheduled paths can post automatically without a human review step.

Install only if you intend this skill to publish to X on your behalf. Before using it, change the default runner and cron jobs to generate drafts only, review the final post text manually, and confirm which authenticated posting account the companion autopost skill will use.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run_briefing.py:44
Finding

Automatic Publication of Unsanitized External Content

Content
View full analysis

Vulnerability Details

File Location: scripts/run_briefing.py:44-48, 51-70, 91-103, 137-140, 169-174; scripts/run-briefing.sh:7
Vulnerability Type: Untrusted external content used in an automatic social-media publishing sink
Risk Level: High

Vulnerable Code

python
def fetch_profile_markdown(handle: str, timeout: int = 25) -> str:
    url = f"https://r.jina.ai/http://x.com/{handle}"
    r = requests.get(url, timeout=timeout)
    r.raise_for_status()
    return r.text
python
def extract_signal_lines(md: str, max_lines: int = 8) -> List[str]:
    lines = [ln.strip() for ln in md.splitlines()]
    cleaned = []
    bad_prefixes = (
        "Title:", "URL Source:", "Published Time:", "Markdown Content:",
        "Pinned", "Quote", "[![Image", "![Image"
    )
    for ln in lines:
        if not ln or len(ln) < 40 or len(ln) > 320:
            continue
        if ln.startswith(bad_prefixes):
            continue
        if re.match(r"^@?[A-Za-z0-9_\.-]+$", ln):
            continue
        if "http" in ln and len(ln) < 80:
            continue
        if ln in cleaned:
            continue
        cleaned.append(ln)
        if len(cleaned) >= max_lines:
            break
    return cleaned
python
md = fetch_profile_markdown(h)
lines = extract_signal_lines(md, max_lines=6)
if not lines:
    unavailable.append((h, name, "页面可读但未提取到有效近况"))
    continue

total_lines += len(lines)
bullets = "\n".join([f"- {x}" for x in lines[:4]])
section = (
    f"### @{h} ({name})\n"
    f"- 近{days}天可见高信号摘录(基于公开页面抓取):\n"
    f"{bullets}\n"
)
sections.append(section)
top_items.append({"handle": h, "name": name, "line": lines[0]})
python
tweet = "📊 AI Creator Briefing ({date})\n\nTop updates:\n{items}\n\nFull briefing saved in workspace reports.\n\n#AI #OpenClaw #Agent".format(
    date=date_str,
    items="\n".join([f"{i+1}. @{it['handle']}: {it['line'][:90]}" for i, it in enumerate(top_items[:3])]) or "1. No strong public updates captured
...[truncated 2965 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make draft-only behavior the default. Remove --publish from scripts/run-briefing.sh and require a separate, explicit publication action.
  2. Add a human approval gate that displays the exact final tweet and requires confirmation immediately before invoking the posting tool.
  3. Treat mirror output as untrusted input. Parse structured post records rather than selecting arbitrary page lines.
  4. Validate post provenance, author identity, post URL, and timestamp. Enforce the requested date window before content becomes eligible.
  5. Allow only expected text characters and normalize Unicode. Remove bidirectional controls, zero-width characters, unexpected line breaks, and other control characters.
  6. Reject or neutralize external URLs and mentions unless they pass explicit allowlists. Revalidate the fully rendered tweet rather than only individual source lines.
  7. Apply the configured keyword, engagement, active-account, and content-safety filters in code. Fail closed when extraction or validation is ambiguous.
  8. Add integrity and availability controls for the external mirror, or use an authenticated and structured upstream API where feasible.
  9. Record the exact source post URL and validation decisions in metadata so operators can audit why content was selected.
  10. Ensure scheduled jobs generate drafts only, or route drafts into an approval queue instead of directly publishing them.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (14)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill advertises '自动发布' and later includes cron-based scheduled execution, but the top-level description does not prominently warn that it can post to external platforms on the user's behalf. This creates a meaningful risk of unintended outbound actions, account misuse, reputational damage, and automated posting without informed consent.

Content

No source excerpt is available for this finding.

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

The script takes untrusted external content scraped from public profiles, transforms it minimally, and can pass it to an autoposting workflow without any content safety validation or human review. Even if Python-level shell injection is avoided, this is still an output-handling vulnerability because attacker-controlled text can trigger harmful downstream behavior such as posting abusive, misleading, policy-violating, or platform-manipulative content from the operator's account.

Content

Scanner excerpt · scripts/run_briefing.py (reported line 171)May include surrounding context.

python
if args.publish:
        try:
            subprocess.run(["bash", str(TWEET_SCRIPT), result["tweet"], "https://x.com"], check=True)
            meta["published"] = True
        except Exception as e:
            meta["publishError"] = str(e)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document explicitly states that the workflow will '自动发布到X' as part of an enabled scheduled task, but it does not warn the user that content will be published externally without an approval checkpoint. In agent or automation contexts, undocumented autonomous posting can lead to unintended disclosure, reputational harm, or policy violations if generated content is inaccurate or sensitive.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README advertises automatic publishing to X and other platforms but does not clearly warn that the skill may post content on a user's behalf to public accounts. In an agent/automation context, this can cause unintended irreversible public actions, reputational damage, or accidental posting to the wrong account if users run the workflow without understanding its side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The cron examples schedule unattended execution of the full workflow, which appears to include publishing behavior via the same run script. Automated recurring execution against external platforms is riskier than one-off manual use because it can repeatedly post generated content, amplify mistakes, and operate long after configuration drift or account changes occur.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger conditions are broad enough to activate on generic phrases like '抓取推文', '生成简报', or any mention of a creator name plus '推文', which can cause the skill to run in contexts where the user did not intend automated scraping/posting behavior. In this skill, that risk is amplified because activation can lead into a workflow that performs external data collection and eventual publishing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented workflow refines output into English for posting and presents this as the default posting path, without requiring user selection of language or confirming that the account owner wants English-language content published. In a multi-language skill, forcing a posting language can lead to misleading or brand-inconsistent output and unintended public communications.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

A tool described as a briefing generator also contains an optional publication path that can send externally fetched and automatically assembled content to a live social platform. That extra capability expands the trust boundary and can cause unintended external actions, especially if operators assume the script is read-only reporting automation.

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

python
if args.publish:
        try:
            subprocess.run(["bash", str(TWEET_SCRIPT), result["tweet"], "https://x.com"], check=True)
            meta["published"] = True
        except Exception as e:
            meta["publishError"] = str(e)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown template presents all user-facing headings and labels in Chinese, which imposes a specific language on generated output. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The task configuration presents schedule and status information in a fixed locale context ('每天 8:00', '下次执行时间', 'GMT+8') while also mixing English headings, with no indication that the locale or language is user-selectable. Under the policy, forcing a specific language/locale without user opt-in can be a natural-language policy issue unless clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Natural-language policy issues include forcing a specific language without user opt-in. This README presents all operational guidance and warnings only in Chinese, with no indication that the skill is region-specific or that other language options are available.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The configuration sets timezone: "Asia/Shanghai" as the default publishing schedule, which imposes a specific locale setting. Under the policy, locale constraints should either be user-selectable or clearly documented as region-specific and justified; this file provides neither.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring explicitly states it 'Drafts English tweet', which imposes a language choice in natural-language behavior. There is no indication that the user can choose the language or opt into English-only output.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.