Changeset 3490158
- Timestamp:
- 03/24/2026 03:19:13 PM (12 days ago)
- Location:
- webmcp-bridge/trunk
- Files:
-
- 3 edited
-
includes/class-tools-core.php (modified) (3 diffs)
-
readme.txt (modified) (2 diffs)
-
webmcp-bridge.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
webmcp-bridge/trunk/includes/class-tools-core.php
r3490060 r3490158 271 271 $markdown = Mescio_For_Agents_Markdown::post_to_markdown( $post ); 272 272 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 273 279 $language = class_exists( 'Mescio_For_Agents_I18n' ) 274 280 ? Mescio_For_Agents_I18n::detect_post_language( $post ) … … 291 297 } 292 298 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  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 293 361 public function tool_get_llms_txt( $params ) { 294 362 if ( ! class_exists( 'Mescio_For_Agents_Rest' ) ) { … … 310 378 throw new Exception( esc_html__( 'Could not retrieve full llms content from Mescio for Agents.', 'webmcp-bridge' ) ); 311 379 } 380 381 // Sanitize the full content for the same reasons as get_markdown_content. 382 $body = $this->sanitize_markdown( $body ); 312 383 313 384 $context['content'] = $body; -
webmcp-bridge/trunk/readme.txt
r3490060 r3490158 4 4 Requires at least: 6.0 5 5 Tested up to: 6.9 6 Stable tag: 1.3. 06 Stable tag: 1.3.1 7 7 Requires PHP: 8.0 8 8 License: GPLv2 or later … … 135 135 == Changelog == 136 136 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 137 140 = 1.2.0 = 138 141 * Added Live API Examples section in admin: test every tool directly from the settings page -
webmcp-bridge/trunk/webmcp-bridge.php
r3490060 r3490158 4 4 * Plugin URI: https://wordpress.org/plugins/webmcp-bridge/ 5 5 * 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. 06 * Version: 1.3.1 7 7 * Requires at least: 6.0 8 8 * Requires PHP: 8.0 … … 17 17 if ( ! defined( 'ABSPATH' ) ) exit; 18 18 19 define( 'WEBMCP_BRIDGE_VERSION', '1.3. 0' );19 define( 'WEBMCP_BRIDGE_VERSION', '1.3.1' ); 20 20 define( 'WEBMCP_BRIDGE_DIR', plugin_dir_path( __FILE__ ) ); 21 21 define( 'WEBMCP_BRIDGE_URL', plugin_dir_url( __FILE__ ) );
Note: See TracChangeset
for help on using the changeset viewer.