Back to skill

Security audit

Wopdpress AI Blogger

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed WordPress publishing helper, but users should treat its live publishing, credential handling, and insecure troubleshooting examples carefully.

Install only if you intend to let an agent create or update content on a WordPress site. Use a dedicated low-privilege WordPress account, keep posts as drafts until reviewed, confirm the exact WP_URL before writes, do not put real passwords directly in shell commands, and avoid copying the verify=False or wildcard credentialed CORS troubleshooting examples into any real environment.

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

T09 · Insecure Skill Coding Practices

Error
Location
references/troubleshooting.md:160
Finding

Authenticated requests may disable TLS certificate verification

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/block_generator.py:118
Finding

Markdown input is inserted into Gutenberg HTML without contextual escaping or URL validation

Content
View full analysis
{link_text}

' blocks.append(self.custom_block('core/paragraph', {}, paragraph)) ``` ```python def convert_inline_markdown(self, text: str) -> str: """Convert inline markdown to HTML.""" # Bold: **text** or __text__ text = re.sub(r'\*\*(.+?)\*\*', r'\1', text) text = re.sub(r'__(.+?)__', r'\1', text) # Italic: *text* or _text_ text = re.sub(r'\*(.+?)\*', r'\1', text) text = re.sub(r'_(.+?)_', r'\1', text) # Code: `text` text = re.sub(r'`(.+?)`', r'\1', text) # Links: [text](url) text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'\1', text) return text ``` ```python heading_html = f'{text}' if anchor: heading_html = f'{text}' ``` ```python list_html = f'<{list_tag}>\n' for item in items: list_html += f'
  • {item}
  • \n' list_html += f'' ``` ```python code_html = f'
    text
    {code}
    ' if language != 'plaintext': code_html = f'
    text
    {code}
    ' ``` ```python image_html = f'' image_html += f'{alt_text}' if caption: image_html += f'{caption}' attrs['caption'] = caption ``` ### Technical Analysis The generator directly interp ...[truncated 2434 chars]
    Remediation
    View remediation
    `. - Attribute values: additionally escape quotation marks. - Code blocks: always HTML-escape the code instead of treating it as markup. 3. Parse URLs with `urllib.parse.urlsplit` and allowlist acceptable schemes: - Prefer `https`. - Allow `http` only when explicitly required. - Reject `javascript`, `vbscript`, and unexpected `data` URLs. 4. Use a maintained Markdown parser configured to reject or escape raw HTML rather than implementing Markdown transformation with regular expressions. 5. Sanitize the final generated fragment with an allowlist-based HTML sanitizer before publication. 6. Restrict elements and attributes to those required by supported Gutenberg blocks. 7. Test the generator against malicious cases involving: - Quotes in URLs and alt text. - Raw `

    T09 · Insecure Skill Coding Practices

    Warning
    Location
    references/troubleshooting.md:142
    Finding

    Troubleshooting guidance recommends unsafe credentialed CORS headers

    Content
    View full analysis
    Remediation
    View remediation
    Vulnerability Patterns
    • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
    • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
    • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
    • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
    • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
    Findings (23)

    Tp4

    High
    Category
    MCP Tool Poisoning
    Confidence
    98% confidence
    Finding

    The code’s actual purpose is narrower than the declared description. It only parses markdown/text and emits Gutenberg block markup for paragraphs, headings, lists, code blocks, quotes, images, separators, groups, columns, and inline markdown conversion. While this does align with the 'Gutenberg block serialization' portion of the description, it does not implement the central claimed capabilities of managing WordPress posts through the REST API. Because the declared purpose emphasizes end-to-end WordPress publishing automation and the code only provides content formatting/serialization, this is a material description-behavior mismatch.

    Content

    No source excerpt is available for this finding.

    Tp4

    High
    Category
    MCP Tool Poisoning
    Confidence
    96% confidence
    Finding

    The declared description centers on automating WordPress post publishing and management through the REST API, including post creation/editing, publishing workflows, taxonomy assignment, featured images, and Gutenberg block handling. The supplied code instead focuses on uploading and updating media assets in the WordPress media library. While it does interact with WordPress over the REST API and includes a small Gutenberg-related convenience feature (example image block snippets in a generated report), its primary purpose is materially different: media upload/metadata management, not post lifecycle automation. This is a substantive description-behavior mismatch rather than a minor omission.

    Content

    No source excerpt is available for this finding.

    Hidden Instructions

    High
    Category
    Prompt Injection
    Confidence
    70% confidence
    Finding

    Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

    Content

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

    md
    # Create block comment
            attrs_json = json.dumps(attrs) if attrs else ''
            block_comment = f'<!-- wp:{block_name} {attrs_json} -->'
            block_html.append(f'{block_comment}{inner_html}<!-- /wp:{block_name} -->')
        
        content = '\n\n'.join(block_html)
    

    Tool Parameter Abuse

    High
    Category
    Tool Misuse
    Confidence
    80% confidence
    Finding

    Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

    Content

    Scanner excerpt · references/api_reference.md (reported line 63)May include surrounding context.

    Delete post

    text
    DELETE /posts/{id}
    

    Add ?force=true to bypass trash.

    Hidden Instructions

    High
    Category
    Prompt Injection
    Confidence
    70% confidence
    Finding

    Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

    Content

    Scanner excerpt · references/common_blocks.md (reported line 10)May include surrounding context.

    Each block is wrapped in HTML comments:

    text
    <!-- wp:block-name {json_attributes} -->
    Block content (HTML)
    <!-- /wp:block-name -->
    

    Hidden Instructions

    High
    Category
    Prompt Injection
    Confidence
    70% confidence
    Finding

    Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

    Content

    Scanner excerpt · references/common_blocks.md (reported line 146)May include surrounding context.

    Preformatted

    html
    <!-- wp:preformatted -->
    <pre class="wp-block-preformatted">This text
       preserves
          whitespace
    

    Undeclared Tool Scope

    Medium
    Category
    MCP Least Privilege
    Confidence
    83% confidence
    Finding

    The skill documents code that reads environment variables, local files, and performs network requests, but it does not declare any tool scope or permissions boundary. In an agent setting, this can cause the skill to be invoked with broader capabilities than users expect, increasing the chance of unintended credential access, file access, or remote modification of a WordPress site.

    Content

    No source excerpt is available for this finding.

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    93% confidence
    Finding

    The skill provides instructions for creating posts, uploading media, and publishing drafts without clearly warning that these are live write operations that can modify production content and make content public. In an autonomous or semi-autonomous agent workflow, that missing warning increases the risk of accidental defacement, premature publication, or unauthorized content changes.

    Content

    No source excerpt is available for this finding.

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    70% confidence
    Finding

    Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

    Content

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

    md
    password = "password"
    
    # Get token
    resp = requests.post(f"{wp_url}/wp-json/jwt-auth/v1/token", 
                         json={"username": username, "password": password})
    token = resp.json()['token']
    

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    84% confidence
    Finding

    This function sends post content to a remote WordPress API and can create content on an external system. In the context of an agent skill, outbound write operations are security-relevant because they can publish sensitive, incorrect, or policy-violating content if invoked without strong confirmation and target validation.

    Content

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

    python
    def create_post(post_data):
        """Create new WordPress post."""
        response = requests.post(f"{wp_url}/wp-json/wp/v2/posts",
                                 json=post_data, auth=auth)
        return response.json()
    

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    92% confidence
    Finding

    This call changes a post's status to publish, which can immediately make content publicly visible on a live site. In agent environments, publish actions are higher risk than ordinary API calls because a mistaken invocation can cause reputational damage, leak sensitive information, or violate change-control requirements.

    Content

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

    python
    def publish_post(post_id):
        """Publish a draft post."""
        response = requests.post(f"{wp_url}/wp-json/wp/v2/posts/{post_id}",
                                 json={"status": "publish"}, auth=auth)
        return response.json()
    

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    70% confidence
    Finding

    Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

    Content

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

    md
    if categories:
            return categories[0]['id']
        else:
            new_cat = requests.post(f"{wp_url}/wp-json/wp/v2/categories",
                                   json={"name": name, "slug": slug or name.lower()},
                                   auth=auth).json()
            return new_cat['id']
    

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    88% confidence
    Finding

    The curl example demonstrates passing the application password directly on the command line, which can expose credentials through shell history, process listings, or logs. Even though the secret is redacted in the example, modeling this pattern encourages insecure operational handling of credentials.

    Content

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

    Example Request

    bash
    # Using curl with Application Password
    curl -X POST https://your-site.com/wp-json/wp/v2/posts \
      -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx" \
      -H "Content-Type: application/json" \
    

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    93% confidence
    Finding

    This markdown file describes deleting posts and explicitly notes that ?force=true bypasses trash, but it does not warn users that this can permanently remove content. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or system integrity.

    Content

    No source excerpt is available for this finding.

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    60% confidence
    Finding

    Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

    Content

    Scanner excerpt · references/api_reference.md (reported line 245)May include surrounding context.

    • API base: https://public-api.wordpress.com/wp/v2/sites/{site_id}/
    • Requires application registration

    Testing with curl

    bash
    # Create post with Application Password
    

    External Transmission

    Medium
    Category
    Data Exfiltration
    Confidence
    60% confidence
    Finding

    Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

    Content

    Scanner excerpt · references/troubleshooting.md (reported line 29)May include surrounding context.

    1. Verify token expiration (default 7 days).
    2. Use curl to test:
      bash
      curl -X POST https://site.com/wp-json/jwt-auth/v1/token \
        -H "Content-Type: application/json" \
        -d '{"username":"admin","password":"password"}'
      

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    96% confidence
    Finding

    The CORS example sets Access-Control-Allow-Origin: * while also allowing credentialed requests, which encourages an unsafe cross-origin configuration. In a WordPress API publishing skill that handles authenticated content operations, this can expose authenticated endpoints to abuse from arbitrary origins or lead users to deploy an overly permissive policy that weakens browser-based protections.

    Content

    No source excerpt is available for this finding.

    Autonomous Decision Making

    Medium
    Category
    Excessive Agency
    Confidence
    91% confidence
    Finding

    The guide presents disabling certificate verification as a troubleshooting step, which is an unsafe security decision delegated to the user without sufficient guardrails. In an automation context that performs authenticated WordPress actions, this can cause clients to accept spoofed servers and leak credentials or publish content through a tampered connection.

    Content

    Scanner excerpt · references/troubleshooting.md (reported line 161)May include surrounding context.

    Problem: Certificate verification fails.

    Solutions:

    1. Self-signed certs: Disable verification (not recommended for production).
      python
      # Python requests
      requests.post(url, auth=auth, verify=False)
      

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    94% confidence
    Finding

    The troubleshooting guide recommends disabling TLS certificate verification and using HTTP for development without a strong warning about the security consequences. Even though marked 'not recommended for production,' this normalizes insecure transport practices that can enable man-in-the-middle attacks, credential theft, and tampering during testing or accidental reuse in higher environments.

    Content

    No source excerpt is available for this finding.

    Unsafe Defaults

    Medium
    Category
    Tool Misuse
    Confidence
    97% confidence
    Finding

    verify=False disables TLS certificate validation, creating an unsafe default troubleshooting pattern that users may copy directly into production scripts. For a skill handling WordPress authentication and publishing, that exposes credentials, tokens, and content operations to interception and manipulation by attackers on the network path.

    Content

    Scanner excerpt · references/troubleshooting.md (reported line 164)May include surrounding context.

    1. Self-signed certs: Disable verification (not recommended for production).
      python
      # Python requests
      requests.post(url, auth=auth, verify=False)
      
    2. Missing intermediate certificates: Install full certificate chain.
    3. Use HTTP: Only for local development.

    Description-Behavior Mismatch

    Medium
    Category
    Not specified by scanner
    Confidence
    96% confidence
    Finding

    The manifest describes a skill for creating, editing, and publishing WordPress posts with features like featured images and Gutenberg block serialization, but this file implements a separate media-uploader utility that uploads arbitrary media files, batch-imports from directories/CSV, and updates existing media metadata. Managing the media library directly is related to WordPress, but it is broader than the manifest’s declared post-centric behavior and is not mentioned in the description.

    Content

    No source excerpt is available for this finding.

    Missing User Warnings

    Medium
    Category
    Not specified by scanner
    Confidence
    85% confidence
    Finding

    This code can transition a draft into a publicly published WordPress post as soon as publish_immediately is set, which is a potentially irreversible content-disclosure action. Although the script's overall purpose is publishing, there is no runtime confirmation prompt before making a live post public, increasing the risk of accidental publication.

    Content

    No source excerpt is available for this finding.

    Description-Behavior Mismatch

    Low
    Category
    Not specified by scanner
    Confidence
    88% confidence
    Finding

    Beyond interacting with the WordPress REST API, the code generates local output artifacts such as upload reports and a JSON file of uploaded media IDs. The manifest describes API-based post management features, but does not mention local file generation or persistent local bookkeeping.

    Content

    No source excerpt is available for this finding.

    Static analysis

    No suspicious patterns detected.