mirror of
https://github.com/Heretek-AI/heretek-control-core.git
synced 2026-10-12 02:03:55 +00:00
Seven findings, all verified against the code first. None is reachable by an anonymous visitor: each needs an administrator, or a URL an administrator already asked the plugin to fetch. F-01, the one that mattered. safe_download() checked the URL you gave it with the strong guard, then handed redirects to WP_Http with reject_unsafe_urls, which only applies core's weaker check. The file's own comment already said core does not reject 169.254.0.0/16, so a URL could pass and then bounce to the cloud metadata service, with the response written into the Media Library. Redirects are now followed by hand with the full check on every hop. The address check itself also read only the first A record, so a host publishing one public and one internal address passed: host_is_blocked() now requires every answer, A and AAAA, to be public, and fails closed when a host resolves to nothing. Rebinding is still out of scope here and the docblock says so. F-02. search-files judged and read each hit by the path it walked, which for a symlink is the link. Its basename defeated the secret check and reading it followed the link out of ABSPATH, so a link named notes.txt pointing at wp-config.php answered a search for DB_PASSWORD. Every hit now goes through resolve_path() first, which is what read-file already did. Listings label symlinks instead of presenting them as files. F-04. The read-protected list was one exact filename. Now covers .env, wp-config.* copies, .htpasswd, auth.json, key files, and anything under .git. .htaccess stays readable on purpose: it is not a secret. F-03. The proxy disabled certificate verification for any host ending in .dev, which is a real gTLD anyone can register, while sending an Application Password on every request. Removed; EMCP_INSECURE_TLS=1 is the opt-in. Package to 1.11.0 since it is published. F-05. Two sandbox guards used wp_normalize_path(), which does not resolve "..", so the containment check they exist to make did not hold. Both resolve properly now. Defense in depth: the hash check beside them is what actually held. F-06. The update package URL is now asserted to be a release asset of this repository before the upgrader is handed it. F-07. The snippet validator skipped every method call, so a function on its critical list reached as $file->fwrite() was never looked up. Reported as a warning rather than critical, because a name alone does not identify the object and falsely blocking someone's $wpdb->query() is worse than a line a reviewer reads. One correction to the report: validate_pinned() is not "called from nowhere". The Pro AI Chat fetcher uses it per hop with CURLOPT_RESOLVE pinning; the scan could not see pro/. Live-verified on msrplugins.test: the six address cases behave, a real 119KB download still completes through the rewritten loop, redirect targets to metadata and RFC1918 are refused, and a refused download leaves no temp file behind. Suites: pro 2541, public 155, proxy 14.
42 lines
990 B
JSON
42 lines
990 B
JSON
{
|
|
"name": "@msrbuilds/emcp-proxy",
|
|
"version": "1.11.0",
|
|
"description": "stdio↔HTTP proxy that connects MCP clients (Claude Desktop, Claude Code, etc.) to one or many remote WordPress sites running the MCP Tools for Elementor (EMCP) plugin.",
|
|
"type": "module",
|
|
"bin": {
|
|
"emcp-proxy": "mcp-proxy.mjs"
|
|
},
|
|
"main": "./mcp-proxy.mjs",
|
|
"files": [
|
|
"mcp-proxy.mjs",
|
|
"README.md"
|
|
],
|
|
"engines": {
|
|
"node": ">=18"
|
|
},
|
|
"license": "GPL-2.0-or-later",
|
|
"author": "MSR Builds",
|
|
"homepage": "https://emcptools.com/docs/connecting/claude-desktop/",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+https://github.com/msrbuilds/elementor-mcp.git",
|
|
"directory": "bin"
|
|
},
|
|
"bugs": {
|
|
"url": "https://github.com/msrbuilds/elementor-mcp/issues"
|
|
},
|
|
"keywords": [
|
|
"mcp",
|
|
"model-context-protocol",
|
|
"elementor",
|
|
"wordpress",
|
|
"claude",
|
|
"claude-desktop",
|
|
"proxy",
|
|
"stdio"
|
|
],
|
|
"publishConfig": {
|
|
"access": "public"
|
|
}
|
|
}
|