Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix: Restrict MCP HTTP transport to localhost, add origin validation by taylorodell · Pull Request #1 · cloudinary/analysis-mcp · GitHub
Skip to content

fix: Restrict MCP HTTP transport to localhost, add origin validation - #1

Open
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding
Open

fix: Restrict MCP HTTP transport to localhost, add origin validation#1
taylorodell wants to merge 1 commit into
cloudinary:mainfrom
taylorodell:fix/restrict-transport-binding

Conversation

@taylorodell

Copy link
Copy Markdown

Summary

This PR fixes a security vulnerability where both the Streamable HTTP (serve) and SSE (start) transports bind to 0.0.0.0 with wildcard CORS (Access-Control-Allow-Origin: *), exposing the MCP server to DNS rebinding and LAN-based attacks.

The Problem

  1. 0.0.0.0 bind exposes the server to the entire local network
  2. ACAO: * allows any webpage to make cross-origin requests to the MCP server
  3. No origin validation means a malicious page (via DNS rebinding) or any LAN device can invoke all MCP tools with the victim's Cloudinary API credentials

Combined, a user running the server with their API credentials (as shown in DOCKER.md) is vulnerable to credential theft from any browser tab they have open.

Precedent: HackerOne resolved report — "DNS Rebinding SSRF in Burp Suite MCP Server" ($2,000 bounty)

Changes

  • Default bind changed from 0.0.0.0 to 127.0.0.1 (both serve and start commands)
  • Added --host CLI flag for users who explicitly need network access (e.g., Docker)
  • Removed wildcard CORS — replaced with origin validation middleware
  • Added --allowed-origins flag (serve command) for users who need cross-origin access from known clients
  • Updated DOCKER.md — Docker examples now use --host 0.0.0.0 (required inside containers) with -p 127.0.0.1:2718:2718 for localhost-only exposure
  • Added Security Considerations section to DOCKER.md
  • Warning logged when --host 0.0.0.0 is used explicitly

Breaking Change Note

Users running the server with network access will need to add --host 0.0.0.0 explicitly. The default is now localhost-only, which is the correct security posture for a credential-bearing local server.

Testing

  • TypeScript compilation: ✅ passes (npx tsc --noEmit)
  • ESLint: ✅ no violations
  • Existing behavior preserved for localhost usage (no CORS needed for same-origin)
  • Docker usage documented with required --host 0.0.0.0 flag

…dcard CORS
- Change default bind address from 0.0.0.0 to 127.0.0.1 for both
serve (Streamable HTTP) and start (SSE) commands
- Remove Access-Control-Allow-Origin: * wildcard CORS header
- Replace with origin validation middleware that only sets CORS headers
for explicitly allowed origins via --allowed-origins flag
- Add --host CLI flag to both commands for users who need network access
- Add --allowed-origins flag to serve command for cross-origin clients
- Log a warning when --host 0.0.0.0 is used explicitly
- Update DOCKER.md examples to use --host 0.0.0.0 (required inside
containers) and recommend -p 127.0.0.1:2718:2718 for localhost-only
port exposure
- Add Security Considerations section to DOCKER.md
Without these changes, the MCP server is vulnerable to DNS rebinding
attacks: a malicious webpage can use DNS rebinding to make cross-origin
requests to the locally-running server, gaining full access to all MCP
tools with the victim's Cloudinary API credentials. The wildcard CORS
policy (ACAO: *) further enables direct cross-origin exploitation from
any webpage without DNS rebinding.
Precedent: HackerOne #2len resolved (Burp Suite MCP DNS rebinding).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@taylorodell