Plugin Directory

Changeset 3490158


Ignore:
Timestamp:
03/24/2026 03:19:13 PM (12 days ago)
Author:
vinsmach
Message:

Version 1.3.2: fix problem

Location:
webmcp-bridge/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • webmcp-bridge/trunk/includes/class-tools-core.php

    r3490060 r3490158  
    271271        $markdown = Mescio_For_Agents_Markdown::post_to_markdown( $post );
    272272
     273        // Sanitize the Markdown output before returning it to the agent.
     274        // A WordPress editor can insert arbitrary JS/HTML in post content.
     275        // Without this step, stored XSS in the post would be forwarded verbatim
     276        // to the AI agent — enabling prompt injection attacks via post content.
     277        $markdown = $this->sanitize_markdown( $markdown );
     278
    273279        $language = class_exists( 'Mescio_For_Agents_I18n' )
    274280            ? Mescio_For_Agents_I18n::detect_post_language( $post )
     
    291297    }
    292298
     299    /**
     300     * Sanitize Markdown content before sending it to an AI agent.
     301     *
     302     * Threats addressed:
     303     *   1. HTML tags surviving the Markdown conversion (script, iframe, etc.)
     304     *      — could be injected by a WordPress editor into post content.
     305     *   2. Inline event handlers (onclick=, onerror=, onload=, etc.)
     306     *      — JS execution vectors embedded in HTML attributes.
     307     *   3. javascript: and data: URIs in Markdown links/images
     308     *      — [click me](javascript:alert(1))
     309     *   4. Basic prompt injection patterns
     310     *      — text designed to hijack the AI agent's instructions.
     311     *
     312     * @param  string $markdown Raw Markdown from Mescio.
     313     * @return string           Sanitized Markdown safe to send to an agent.
     314     */
     315    private function sanitize_markdown( string $markdown ): string {
     316
     317        // 1. Strip dangerous HTML tags entirely (including their content for script/style).
     318        $dangerous_tags = 'script|style|iframe|object|embed|form|input|button|textarea|select|link|meta|base';
     319        $markdown = preg_replace(
     320            '/<(' . $dangerous_tags . ')[^>]*>.*?<\/\1>/is',
     321            '',
     322            $markdown
     323        );
     324
     325        // 2. Strip any remaining HTML tags that survived (keep text content).
     326        //    wp_kses with an empty allowed list strips all tags but keeps text.
     327        $markdown = wp_kses( $markdown, [] );
     328
     329        // 3. Neutralize javascript: and data: URIs in Markdown links and images.
     330        //    Matches: [text](javascript:...) and ![alt](data:...)
     331        $markdown = preg_replace(
     332            '/(\[.*?\]\()(?:javascript|data|vbscript):[^\)]*(\))/i',
     333            '$1#removed$2',
     334            $markdown
     335        );
     336
     337        // 4. Strip inline event handlers (onclick=, onerror=, etc.)
     338        $markdown = (string) preg_replace(
     339            '/\s+on[a-z]+\s*=\s*(["\'])(?:(?!\1).)*\1/i',
     340            '',
     341            (string) $markdown
     342        );
     343
     344        // 5. Detect and neutralize obvious prompt injection attempts.
     345        //    These are heuristic — they flag content that looks like instructions
     346        //    directed at an AI system rather than normal editorial content.
     347        $injection_patterns = [
     348            '/ignore\s+(all\s+)?(previous|prior|above)\s+instructions?/i',
     349            '/disregard\s+(all\s+)?(previous|prior|above)\s+instructions?/i',
     350            '/you\s+are\s+now\s+(a\s+)?[\w\s]+assistant/i',
     351            '/system\s*:\s*(you\s+are|act\s+as|pretend)/i',
     352            '/\[INST\]|\[\/INST\]|<\|im_start\|>|<\|im_end\|>/i',
     353        ];
     354        foreach ( $injection_patterns as $pattern ) {
     355            $markdown = preg_replace( $pattern, '[removed]', $markdown );
     356        }
     357
     358        return trim( $markdown );
     359    }
     360
    293361    public function tool_get_llms_txt( $params ) {
    294362        if ( ! class_exists( 'Mescio_For_Agents_Rest' ) ) {
     
    310378                throw new Exception( esc_html__( 'Could not retrieve full llms content from Mescio for Agents.', 'webmcp-bridge' ) );
    311379            }
     380
     381            // Sanitize the full content for the same reasons as get_markdown_content.
     382            $body = $this->sanitize_markdown( $body );
    312383
    313384            $context['content']         = $body;
  • webmcp-bridge/trunk/readme.txt

    r3490060 r3490158  
    44Requires at least: 6.0
    55Tested up to: 6.9
    6 Stable tag: 1.3.0
     6Stable tag: 1.3.1
    77Requires PHP: 8.0
    88License: GPLv2 or later
     
    135135== Changelog ==
    136136
     137= 1.3.1 =
     138* Security: sanitize Markdown output in get_markdown_content and get_llms_txt before returning to agent — prevents stored XSS / prompt injection via post content
     139
    137140= 1.2.0 =
    138141* Added Live API Examples section in admin: test every tool directly from the settings page
  • webmcp-bridge/trunk/webmcp-bridge.php

    r3490060 r3490158  
    44 * Plugin URI:        https://wordpress.org/plugins/webmcp-bridge/
    55 * Description:       Exposes WordPress functionality as WebMCP tools so AI agents can interact with your site natively in the browser — no backend MCP server required.
    6  * Version:           1.3.0
     6 * Version:           1.3.1
    77 * Requires at least: 6.0
    88 * Requires PHP:      8.0
     
    1717if ( ! defined( 'ABSPATH' ) ) exit;
    1818
    19 define( 'WEBMCP_BRIDGE_VERSION', '1.3.0' );
     19define( 'WEBMCP_BRIDGE_VERSION', '1.3.1' );
    2020define( 'WEBMCP_BRIDGE_DIR', plugin_dir_path( __FILE__ ) );
    2121define( 'WEBMCP_BRIDGE_URL', plugin_dir_url( __FILE__ ) );
Note: See TracChangeset for help on using the changeset viewer.