Back to skill

Security audit

freelance-proposal-gen

Security checks for vulnerabilities and agentic risk

Overview

The skill is a local proposal generator, but it needs Review because client-facing HTML can include default contact branding and unsanitized active content.

Install only if you are comfortable reviewing every generated HTML file before sharing it. Replace or remove the hardcoded contact defaults, set SHOW_CONTACT_WATERMARK to false unless you intentionally want it, and avoid feeding untrusted HTML or client-provided markup into the fields JSON.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T01 · Skill Instruction Hijacking

Error
Location
scripts/generate_proposal.py:31
Finding

Default Third-Party Contact Injection and Promotional Output Hijacking

Content
View full analysis
str: """Build a toggleable corner watermark for lead generation. Shows the creator's name + WeChat + site as a subtle, always-visible brand mark on screen (hidden on print so the client's PDF stays clean). Controlled by SHOW_CONTACT_WATERMARK ('true' by default). """ show = str(fields.get("SHOW_CONTACT_WATERMARK", "true")).strip().lower() \ in ("true", "1", "yes", "on", "y") if not show: return "" name = str(fields.get("YOUR_NAME", "")).strip() wechat = str(fields.get("WECHAT", "")).strip() website = str(fields.get("WEBSITE", "")).strip() parts = [] if name: parts.append(f"提案由 {name} 生成") if wechat: parts.append(f"微信 {wechat}") if website: parts.append(website) if not parts: return "" text = " · ".join(parts) ...[truncated 2469 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_proposal.py:21
Finding

Unescaped Template Substitution Allows Active HTML, Script, and CSS Injection

Content
View full analysis
str: with open(template_path, encoding="utf-8") as f: html = f.read() for key, value in fields.items(): html = html.replace("{{" + str(key).upper() + "}}", str(value)) # Blank any tokens the caller did not supply. html = re.sub(r"\{\{[A-Z_][A-Z0-9_]*\}\}", "", html) return html ``` From `SKILL.md:49-50`: ```markdown Assemble a JSON object whose keys match the template tokens (uppercase). Lists and tables must be passed as ready HTML (`
  • …
  • `, `…`). ``` Representative vulnerable contexts from `assets/proposal-template.html:6-8`: ```html {{PROPOSAL_TITLE}} :root { --accent: {{ACCENT}}; ``` Representative vulnerable contexts from `assets/proposal-template.html:75-125`: ```html <div class="page"> <div class="cover"> <h1>{{PROPOSAL_TITLE}}</h1> <div class="sub">{{PROPOSAL_SUBTITLE}}</div> <div class="meta"> 为 <b>{{PREPARED_FOR}}</b> 定制 &nbsp;·&nbsp; 出具日期 <b>{{DATE}}</b><br/> 提案人:<b>{{YOUR_NAME}}</b> &nbsp;·&nbsp; {{YOUR_TITLE}} </div> </div> <section> <h2>当前挑战</h2> <p class="intro">{{PAIN_INTRO}}</p> <ul class="pain">{{PAIN_POINTS}}</ul> </section> <section> <h2>我们的方案</h2> <p class="intro">{{SOLUTION_INTRO}}</p> {{SOLUTION_BLOCKS}} </section> <section> <h2>交付内容</h2> <ul class="deliv">{{DELIVERABLES}}</ul> </section> <section> <h2>合作方案与报价</h2> <table class="price"> <thead><tr><th>方案</th><th>范围</th><th>报价 ...[truncated 3544 chars]
    Remediation
    View remediation
    Vulnerability Patterns
    • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
    • 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
    • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
    Findings (10)

    Undeclared Tool Scope

    Medium
    Category
    MCP Least Privilege
    Confidence
    91% confidence
    Finding

    The skill instructs the agent to run a local script that writes proposal.html, but the manifest does not declare any tool scope such as file-write permissions or allowed tools. This creates an authorization and containment gap: an agent may perform filesystem writes without explicit user-visible permission boundaries, increasing the risk of unintended file modification or abuse if the skill or downstream prompt is manipulated.

    Content

    No source excerpt is available for this finding.

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    95% confidence
    Finding

    Line L76 states 'All copy Chinese unless the client is explicitly foreign-language,' which imposes a default language policy rather than letting the user choose. This is a natural-language policy concern because it forces a locale/language behavior without explicit user opt-in.

    Content

    No source excerpt is available for this finding.

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    95% confidence
    Finding

    The HTML document hard-codes lang="zh-CN", which imposes a specific language/locale on all generated output. Under the policy, locale constraints should either be optional for the user or clearly justified as region-specific; neither is present in this file.

    Content

    No source excerpt is available for this finding.

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    87% confidence
    Finding

    The natural-language description and most trigger phrases are presented only in Chinese, which implies a fixed language experience for users. There is no indication that users may choose another language or that the locale restriction is intentional and documented as a region-specific requirement.

    Content

    No source excerpt is available for this finding.

    Vague Triggers

    Medium
    Category
    Not specified by scanner
    Confidence
    93% confidence
    Finding

    The trigger list includes very generic phrases such as 'freelance proposal' and common Chinese business-request wording that could match ordinary user intents beyond this skill's narrow purpose. Over-broad activation can cause the wrong skill to engage, leading to unintended handling of user requests, reduced user control, and possible prompt/context confusion in downstream agent behavior.

    Content

    No source excerpt is available for this finding.

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    97% confidence
    Finding

    The spec provides hardcoded personal contact defaults and couples them with watermark behavior, without warning the user that generated outputs may automatically include and propagate this information. In this skill context, proposals are intended to be client-facing and shareable, so silently inserting personal contact details into outputs creates a real privacy, reputational, and unauthorized advertising risk.

    Content

    No source excerpt is available for this finding.

    Description-Behavior Mismatch

    Medium
    Category
    Not specified by scanner
    Confidence
    93% confidence
    Finding

    The script injects a persistent lead-generation watermark containing the creator's branding/contact details by default, even though the skill is described as generating client-ready proposal HTML and does not disclose this behavior in scope. In a sales/proposal context, hidden or unexpected branding can leak operator identity, alter deliverables sent to third parties, and create trust, privacy, or business-integrity issues for users who expect clean client-facing output.

    Content

    No source excerpt is available for this finding.

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    95% confidence
    Finding

    The watermark strings are hardcoded in Chinese ("提案由 ... 生成" and "微信 ...") with no user opt-in or configurable locale. This creates a natural-language policy issue because the skill forces a specific language in generated output regardless of user preference or context.

    Content

    No source excerpt is available for this finding.

    Intent-Code Divergence

    Low
    Category
    Not specified by scanner
    Confidence
    95% confidence
    Finding

    Line L38 defines the cover as including the sender, while L52 states "Bio appears only in the footer." These instructions actively contradict each other about where sender identity information should appear in the generated proposal.

    Content

    No source excerpt is available for this finding.

    Description-Behavior Mismatch

    Low
    Category
    Not specified by scanner
    Confidence
    93% confidence
    Finding

    The spec explicitly requires an always-on contact watermark as a 'lead-gen hook' so shared screenshots or forwarded HTML carry the sender's contact information. In a proposal-generation skill, that means generated outputs may embed promotional or identifying content beyond the user's explicit request, creating undisclosed data-sharing and content-manipulation risk rather than acting as a neutral renderer.

    Content

    No source excerpt is available for this finding.

    Static analysis

    No suspicious patterns detected.