Plugin Directory

Changeset 3479831


Ignore:
Timestamp:
03/11/2026 08:32:53 AM (3 weeks ago)
Author:
royalpluginsteam
Message:

v1.2.3 - SSRF protection, WP 6.9.3 compatible

Location:
royal-mcp/trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • royal-mcp/trunk/assets/js/admin.js

    r3439404 r3479831  
    88    // Copy Buttons
    99    // ==========================================
     10
     11    // Regenerate API key confirmation
     12    $('#rmcp-regenerate-key').on('click', function(e) {
     13        if (!confirm(royalMcp.strings.confirmRegenerate)) {
     14            e.preventDefault();
     15        }
     16    });
    1017
    1118    $('#copy-api-key').on('click', function(e) {
  • royal-mcp/trunk/includes/Admin/Settings_Page.php

    r3439404 r3479831  
    187187                'documentation' => esc_html__('Documentation', 'royal-mcp'),
    188188                'confirmRemove' => esc_html__('Are you sure you want to remove this platform?', 'royal-mcp'),
     189                'confirmRegenerate' => esc_html__('Are you sure? This will invalidate the current API key.', 'royal-mcp'),
    189190            ],
    190191        ]);
  • royal-mcp/trunk/includes/MCP/Client.php

    r3439404 r3479831  
    4747
    4848        $url = trailingslashit($server['url']) . ltrim($endpoint, '/');
     49
     50        // SSRF protection: validate URL before making request
     51        $url_check = \Royal_MCP\Platform\Registry::validate_external_url( $url );
     52        if ( is_wp_error( $url_check ) ) {
     53            return $url_check;
     54        }
    4955
    5056        $args = [
     
    112118        }
    113119
     120        // SSRF protection: validate URL before making request
     121        $url_check = \Royal_MCP\Platform\Registry::validate_external_url( $server['url'] );
     122        if ( is_wp_error( $url_check ) ) {
     123            return [
     124                'success' => false,
     125                'message' => $url_check->get_error_message(),
     126            ];
     127        }
     128
    114129        $response = wp_remote_get($server['url'], [
    115130            'timeout' => 10,
  • royal-mcp/trunk/includes/Platform/Registry.php

    r3439404 r3479831  
    517517     * Get the endpoint URL for a platform
    518518     */
     519    /**
     520     * Validate that a URL is safe for outbound requests (SSRF protection).
     521     *
     522     * @param string $url The URL to validate.
     523     * @return true|\WP_Error True if safe, WP_Error if not.
     524     */
     525    public static function validate_external_url( $url ) {
     526        $parsed = wp_parse_url( $url );
     527
     528        if ( empty( $parsed['scheme'] ) || ! in_array( $parsed['scheme'], array( 'http', 'https' ), true ) ) {
     529            return new \WP_Error( 'invalid_url_scheme', __( 'Only HTTP and HTTPS URLs are allowed.', 'royal-mcp' ) );
     530        }
     531
     532        if ( empty( $parsed['host'] ) ) {
     533            return new \WP_Error( 'invalid_url_host', __( 'URL must include a hostname.', 'royal-mcp' ) );
     534        }
     535
     536        $host = $parsed['host'];
     537
     538        // Block localhost and loopback
     539        $blocked = array( 'localhost', '127.0.0.1', '::1', '0.0.0.0' );
     540        if ( in_array( strtolower( $host ), $blocked, true ) ) {
     541            return new \WP_Error( 'blocked_url', __( 'Localhost and loopback addresses are not allowed.', 'royal-mcp' ) );
     542        }
     543
     544        // Block private and reserved IP ranges
     545        if ( filter_var( $host, FILTER_VALIDATE_IP ) ) {
     546            if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
     547                return new \WP_Error( 'blocked_url', __( 'Private and reserved IP addresses are not allowed.', 'royal-mcp' ) );
     548            }
     549        }
     550
     551        return true;
     552    }
     553
    519554    public static function get_endpoint($platform_id, $config) {
    520555        $platform = self::get_platform($platform_id);
     
    563598        if (!empty($platform['test_endpoint'])) {
    564599            $test_url .= $platform['test_endpoint'];
     600        }
     601
     602        // SSRF protection: validate URL before making request
     603        $url_check = self::validate_external_url( $test_url );
     604        if ( is_wp_error( $url_check ) ) {
     605            return [
     606                'success' => false,
     607                'message' => $url_check->get_error_message(),
     608            ];
    565609        }
    566610
  • royal-mcp/trunk/readme.txt

    r3439404 r3479831  
    22Contributors: royalpluginsteam
    33Donate link: https://www.royalplugins.com
    4 Tags: mcp, ai, api, claude, openai
     4Tags: wordpress mcp, ai integration, claude wordpress, model context protocol, chatgpt wordpress
    55Requires at least: 5.8
    6 Tested up to: 6.9
    7 Stable tag: 1.2.2
     6Tested up to: 6.9.3
     7Stable tag: 1.2.3
    88Requires PHP: 7.4
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1111
    12 Connect AI platforms to your WordPress site using Model Context Protocol (MCP) for seamless content access.
     12WordPress MCP plugin that connects AI platforms like Claude, ChatGPT, and Gemini to your site using Model Context Protocol for secure content access.
    1313
    1414== Description ==
     
    9898Claude, OpenAI, Google Gemini, Mistral, Perplexity, Groq, Cohere, Together AI, DeepSeek, and any platform supporting REST API connections.
    9999
     100= How do I connect Claude to WordPress? =
     101
     102Install Royal MCP, go to Royal MCP → Settings, select Claude as your platform, and enter your Anthropic API key. The plugin provides a REST API endpoint URL and authentication key that you paste into Claude Desktop's MCP configuration. Full setup guide at royalplugins.com/support/royal-mcp/.
     103
     104= Can I use ChatGPT with WordPress? =
     105
     106Yes! Royal MCP supports OpenAI's GPT-4 and GPT-3.5 models. Configure your OpenAI API key in the plugin settings, and ChatGPT can access your WordPress posts, pages, and media through the Model Context Protocol.
     107
     108= What is Model Context Protocol for WordPress? =
     109
     110Model Context Protocol (MCP) is an open standard that lets AI assistants securely read and interact with external data sources. Royal MCP implements this protocol for WordPress, giving AI platforms like Claude, ChatGPT, and Gemini structured access to your site content through authenticated REST API endpoints.
     111
    100112= Does this work with Claude Desktop? =
    101113
     
    113125
    114126= 1.2.3 =
     127* Security: Added SSRF protection — validates all outbound URLs against private/reserved IP ranges and unsafe schemes
    115128* Fixed: Text domain changed from 'wp-royal-mcp' to 'royal-mcp' to match plugin slug
    116129* Fixed: Menu slugs updated from 'wp-royal-mcp' to 'royal-mcp' for WP.org compliance
     
    118131* Improved: REST API permission callbacks now include explanatory comments for reviewers
    119132* Improved: Custom MCP server placeholder text clarified
     133* Compatibility: Tested up to WordPress 6.9.3
    120134
    121135= 1.2.2 =
     
    150164
    151165= 1.2.3 =
    152 WordPress.org compliance fixes: text domain, menu slugs, and documentation improvements.
     166Security: SSRF protection for outbound requests. WordPress.org compliance fixes. Tested with WordPress 6.9.3.
    153167
    154168= 1.2.2 =
  • royal-mcp/trunk/royal-mcp.php

    r3439404 r3479831  
    44 * Plugin URI: https://royalplugins.com/support/royal-mcp/
    55 * Description: Integrate Model Context Protocol (MCP) servers with WordPress to enable LLM interactions with your site
    6  * Version: 1.2.2
     6 * Version: 1.2.3
    77 * Author: Royal Plugins
    88 * Author URI: https://www.royalplugins.com
     
    2121
    2222// Define plugin constants
    23 define('ROYAL_MCP_VERSION', '1.2.2');
     23define('ROYAL_MCP_VERSION', '1.2.3');
    2424define('ROYAL_MCP_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2525define('ROYAL_MCP_PLUGIN_URL', plugin_dir_url(__FILE__));
  • royal-mcp/trunk/templates/admin/logs.php

    r3439404 r3479831  
    132132
    133133<!-- Modal for log details -->
    134 <div id="log-details-modal" class="log-modal" style="display: none;">
     134<div id="log-details-modal" class="log-modal">
    135135    <div class="log-modal-content">
    136136        <span class="log-modal-close">&times;</span>
  • royal-mcp/trunk/templates/admin/settings.php

    r3439404 r3479831  
    7373                                        value="1"
    7474                                        class="button"
    75                                         onclick="return confirm('<?php esc_attr_e('Are you sure? This will invalidate the current API key.', 'royal-mcp'); ?>');">
     75                                        id="rmcp-regenerate-key">
    7676                                    <?php esc_html_e('Regenerate', 'royal-mcp'); ?>
    7777                                </button>
Note: See TracChangeset for help on using the changeset viewer.