Back to skill

Security audit

Build With Public Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent writing helper, but its generated sharing server can expose local files over the network with weak default credentials.

Review carefully before installing. Use the writing-template commands only in a trusted local project, change the generated credentials immediately, avoid exposing the server outside localhost, do not rely on Basic Auth over plain HTTP, and do not serve sensitive directories until the path-containment issue is fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bwp.sh:574
Finding

Arbitrary Local File Disclosure Through Absolute Paths and Symlinks

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bwp.sh:505
Finding

Public Network Binding with Predictable Default Credentials

Content
View full analysis
"$PROJECT_ROOT/.env" << 'ENVEOF' # Build with Public - Environment Configuration # Server port PORT=12000 # Custom domain (optional, for generating shareable links) # CUSTOM_DOMAIN=your-domain.com # Authentication AUTH_USERNAME=user AUTH_PASSWORD=changeme ENVEOF ``` The generated server also embeds the same fallback credentials: ```python CONFIG = {'PORT': 12000, 'AUTH_USERNAME': 'user', 'AUTH_PASSWORD': 'changeme'} if os.path.exists('.env'): with open('.env', 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#') and '=' in line: key, value = line.split('=', 1) CONFIG[key] = value.strip().strip('"').strip("'") PORT = int(CONFIG.get('PORT', 12000)) AUTH_USERNAME = CONFIG.get('AUTH_USERNAME', 'user') AUTH_PASSWORD = CONFIG.get('AUTH_PASSWORD', 'changeme') ``` The server binds to every available interface: ```python def main(): os.chdir(os.path.dirname(os.path.abspath(__file__))) server = HTTPServer(('', PORT), AuthHandler) ``` ### Technical Analysis The generated service uses a fixed username and password that are present in the distributed Skill source. Initialization does not generate a secret or require the user to replace the placeholder before startup. The empty host string in `HTTPServer(('', PORT), ...)` binds the service to all available interfaces rather than only the loopback interface. Consequently, a server intended for simple project sharing may become accessible to other hosts on the local network, container network, cloud network, or public Internet, depending o ...[truncated 1497 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bwp.sh:836
Finding

Basic Authentication Credentials and Content Are Transmitted Over Plaintext HTTP

Content
View full analysis
/dev/null | cut -d= -f2 | tr -d '"' || echo "12000") local custom_domain=$(grep CUSTOM_DOMAIN "$PROJECT_ROOT/.env" 2>/dev/null | cut -d= -f2 | tr -d '"') # Use CUSTOM_DOMAIN if set, otherwise fallback to localhost local hostname="${custom_domain:-localhost}" # Output only the clickable link echo "http://${hostname}:${port}/${file}" ``` ### Technical Analysis HTTP Basic Authentication does not encrypt credentials. It Base64-encodes the `username:password` value and sends that value in the `Authorization` header with authenticated requests. Because generated links explicitly use `http://`, neither the credentials nor the served content receives transport encryption. If a custom domain is configured and used across an untrusted network, any on-path observer can capture the Authorization header, decode the credentials, and reuse them. The pre-scan's decode-related pattern corresponds to decoding Basic Authentication credentials. It does not execute the decoded value and is not a decode-and-execute payload. The security problem is t ...[truncated 1068 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bwp.sh:638
Finding

Stored HTML and Script Injection in Markdown Preview and Directory Listings

Content
View full analysis
📁{f}' for f in sorted(files_only): f_path = os.path.join(safe_path, f) if safe_path != '.' else f html += f'
  • 📄{f}
  • ' html += '' self.wfile.write(html.encode('utf-8')) ``` Markdown content is transformed into HTML without first escaping raw HTML: ```python with open(full_path, 'r', encoding='utf-8') as f: content = f.read() import re html = content ``` User-controlled link and image targets are inserted directly into attributes: ```python # Links [text](url) html = re.sub(r'\[(.+?)\]\((.+?)\)', r'\1', html) # Images ![alt](url) html = re.sub(r'!\[(.+?)\]\((.+?)\)', r'\1', html) ``` The resulting HTML is returned directly: ```python html = f'...{html}' self.wfile.write(html.encode('utf-8')) ``` ### Technical Analysis The preview implementation treats Markdown content as trusted HTML. Raw tags, event-handler attributes, and crafted link or image values are not escaped or sanitized. The regular-expression substitutions also do not validate URL schemes, so unsafe values can be placed into `href` or `src` attributes. Directory listings have the same problem because filenames and generated paths are inserted into HTML text and attributes without HTML or URL escaping. This creates a stored injection cond ...[truncated 1595 chars]
    Remediation
    View remediation
    Vulnerability Patterns
    • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
    • Rogue AgentSelf-Modification, Session Persistence
    • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
    • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
    • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
    Findings (26)

    YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

    High
    Category
    YARA Match
    Confidence
    95% confidence
    Finding

    Appending an alias to ~/.bashrc establishes persistent modification of the user's shell environment. Although presented as optional convenience, persistence in shell startup files is security-relevant because it changes future command behavior and can be abused to mask or redirect execution if the referenced script changes later.

    Content

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

    �用 bwp:

    选项1:直接使用完整路径(推荐,无需修改配置)

    bash
    /home/claw/.openclaw/workspace/skills/build-with-public-writer/scripts/bwp.sh help
    

    选项2:手动添加 alias(可选)

    bash
    # 如果你希望使用简短的 bwp 命令,可以手动添加 alias 到 ~/.bashrc
    # ⚠️ 注意:这会修改你的 shell 配置文件,请审查后再执行
    
    echo 'alias bwp="/home/claw/.openclaw/workspace/skills/build-with-public-writer/scripts/bwp.sh"' >> ~/.bashrc
    source ~/.bashrc
    

    查看帮助:

    bash
    bwp help
    

    核心命令

    场景0: 初始化项目 (必做)

    bash
    bwp init
    

    输出:

    text
    🚀 Initializing Build with Public project...
    
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
      articles/  - Technical articles and blog posts
      courses/   - Course outlines and tutorials
      theory/    - Frameworks and methodologies
      persona/   - Writing pe
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

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

    md
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

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

    md
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

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

    md
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

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

    md
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 322)May include surrounding context.

    sh
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 505)May include surrounding context.

    sh
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 756)May include surrounding context.

    sh
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 767)May include surrounding context.

    sh
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 836)May include surrounding context.

    sh
    ✅ Directory structure created
    ✅ README.md created
    ✅ .env created
    ✅ server.py created
    
    📁 Project structure:
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    83% confidence
    Finding

    The skill states it auto-generates a .env file containing authentication information and a server supporting Basic Auth. Generating auth material and a reachable service without documented secure defaults, rotation guidance, or secret-handling constraints increases the risk of weak credentials, accidental exposure, or unsafe storage.

    Content

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

    md
    **说明**:
    - 创建完整的目录结构
    - 生成 README.md 说明文档
    - 自动生成 .env 配置文件(包含端口、认证信息)
    - 自动生成 server.py Web 服务器(支持 Markdown 渲染和 Basic Auth)
    - 只需执行一次,或在目录缺失时执行
    

    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 · SKILL.md (reported line 193)May include surrounding context.

    🔗 Shareable Link: http://localhost:12000/articles/2026-03-13-ai-trends-v1.md

    👤 Access credentials configured in .env (Check /home/claw/codewithriver/.env for AUTH_USERNAME and AUTH_PASSWORD)

    text

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    80% confidence
    Finding

    Directing users or an agent to check a file for AUTH_USERNAME and AUTH_PASSWORD can normalize secret-file access inside a skill workflow. In agent environments with file-read capability, this can expand the chance of unintended credential disclosure through logs, summaries, or downstream tool use.

    Content

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

    http://localhost:12000/articles/2026-03-13-ai-trends-v1.md

    👤 Access credentials configured in .env (Check /home/claw/codewithriver/.env for AUTH_USERNAME and AUTH_PASSWORD)

    text

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    86% confidence
    Finding

    The example includes AUTH_USERNAME and AUTH_PASSWORD fields in a documented local config schema. While example placeholders are not secrets, normalizing inline auth configuration for a local web server can lead to insecure deployments, especially if users copy weak example values or expose the service beyond localhost.

    Content

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

    bwp link 命令会读取 /home/claw/codewithriver/.env 文件中的配置:

    bash
    # /home/claw/codewithriver/.env
    PORT=12000
    CUSTOM_DOMAIN=your-domain.com  # 可选,用于生成分享链接
    AUTH_USERNAME=user
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    78% confidence
    Finding

    The text says the tool will not display credentials but tells the user to check the .env file directly. In an agent context, that still creates a pathway for secret access because the agent may have local file-read capability and could surface those values inadvertently.

    Content

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

    md
    - `CUSTOM_DOMAIN`: 设置后,`bwp link` 会生成 `http://your-domain.com:PORT/...` 的链接
    - 未设置时,默认使用 `localhost`
    - **注意**: 出于安全考虑,`bwp link` 不会显示实际的凭证值,请直接查看 .env 文件
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 506)May include surrounding context.

    sh
    echo "✅ README.md created"
        
        # Create .env file
        cat > "$PROJECT_ROOT/.env" << 'ENVEOF'
    # Build with Public - Environment Configuration
    
    # Server port
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 837)May include surrounding context.

    sh
    echo "✅ README.md created"
        
        # Create .env file
        cat > "$PROJECT_ROOT/.env" << 'ENVEOF'
    # Build with Public - Environment Configuration
    
    # Server port
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 838)May include surrounding context.

    sh
    echo "✅ README.md created"
        
        # Create .env file
        cat > "$PROJECT_ROOT/.env" << 'ENVEOF'
    # Build with Public - Environment Configuration
    
    # Server port
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    96% confidence
    Finding

    The generated server code initializes default credentials (user / changeme), which is dangerous because users may start the service without changing them. In a content-sharing server, predictable default authentication can allow unauthorized access to all hosted project files if the server is exposed beyond localhost.

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 535)May include surrounding context.

    sh
    CONFIG = {'PORT': 12000, 'AUTH_USERNAME': 'user', 'AUTH_PASSWORD': 'changeme'}
    
    if os.path.exists('.env'):
        with open('.env', 'r') as f:
            for line in f:
                line = line.strip()
    

    Credential Access

    High
    Category
    Privilege Escalation
    Confidence
    60% confidence
    Finding

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

    Content

    Scanner excerpt · scripts/bwp.sh (reported line 536)May include surrounding context.

    sh
    CONFIG = {'PORT': 12000, 'AUTH_USERNAME': 'user', 'AUTH_PASSWORD': 'changeme'}
    
    if os.path.exists('.env'):
        with open('.env', 'r') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#') and '=' in line:
    

    Undeclared Tool Scope

    Medium
    Category
    MCP Least Privilege
    Confidence
    92% confidence
    Finding

    The skill documents shell execution, file access, and local web serving behavior but declares no explicit tool scope or allowed-tools boundary. In an agent setting, this increases the chance that the skill can invoke broader capabilities than a reviewer or user expects, weakening least-privilege controls.

    Content

    No source excerpt is available for this finding.

    Session Persistence

    Medium
    Category
    Rogue Agent
    Confidence
    60% confidence
    Finding

    Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

    Content

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

    md
    ---
    name: build-with-public-writer
    description: Use "bwp" command to create technical content for codewithriver. Supports articles, courses, theory, persona with version management and link sharing
    ---
    
    # Build with Public (bwp) - 技术内容创作系统
    

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    92% confidence
    Finding

    The skill instructions and operational descriptions are written predominantly in Chinese, with no indication that users may choose another language or locale. This creates a language/locale policy concern because the skill appears to assume a specific language experience rather than offering opt-in or alternatives.

    Content

    No source excerpt is available for this finding.

    Natural-Language Policy Violations

    Medium
    Category
    Not specified by scanner
    Confidence
    92% confidence
    Finding

    This shell script contains natural-language comments in Chinese and also generates a README whose visible instructional content is largely Chinese-only. The file does not offer users any language or locale choice, which can violate a language/locale policy when a skill implicitly forces one language without opt-in.

    Content

    No source excerpt is available for this finding.

    Description-Behavior Mismatch

    Medium
    Category
    Not specified by scanner
    Confidence
    94% confidence
    Finding

    The init flow creates and configures a Python HTTP server plus a credential file, which expands the skill from local content scaffolding into network-exposed content hosting. That added attack surface is significant because users invoking a writer helper may not expect it to provision and encourage running a server that can expose project files over the network.

    Content

    No source excerpt is available for this finding.

    Static analysis

    No suspicious patterns detected.