Skip to content

CVE-2025-65512 appears to affect 1.1.0 via URL destination validation bypass #112

Description

@3em0

Summary

webpage-to-markdown URL fetching appears to still be affected by the SSRF class tracked as CVE-2025-65512 in the current repository version (package.json reports 1.1.0). In addition to hostname/DNS-based bypasses, the current validator also accepts bracketed IPv6 loopback URLs such as http://[::1]:<port>/....

The affected path is:

  • server.ts: URL tools (webpage-to-markdown, youtube-to-markdown, bing-search-to-markdown) pass user-controlled url values to Markdownify.toMarkdown.
  • Markdownify.ts: safeFetch() calls validateUrl(currentUrl) and then fetch(currentUrl, { redirect: "manual" }).
  • utils.ts: validateUrl() checks the scheme and then calls private-ip on parsed.hostname, but does not check the resolved destination IP.

Impact

An attacker who can invoke a URL-based MCP tool can cause the server process to fetch loopback, link-local, or otherwise internal HTTP resources if the hostname validation does not reflect the actual network destination. Depending on deployment, this may expose cloud metadata, internal service responses, local admin interfaces, or other network-local data readable by the server process.

This is most severe when the MCP server runs in a cloud/VPC/container environment or is reachable through a remote MCP gateway. In a strictly local, single-user setup, the practical attack surface is lower.

Local verification

I verified the issue locally against the project code without modifying source files:

  1. Started a temporary HTTP server bound only to ::1.
  2. Called the project's URL validation and fetch path with http://[::1]:<port>/metadata.
  3. The validator accepted the URL and the fetch returned the loopback-only response.

Observed result:

{
  "address": "::1",
  "url": "http://[::1]:38069/metadata",
  "validateUrlAccepted": true,
  "responseStatus": 200,
  "responseText": "LOCAL_METADATA_TOKEN"
}

The issue is that security-relevant destination context, especially the resolved IP address, is not part of the authorization decision. Redirect targets are revalidated before following, which is good, but each target still has the same unresolved-IP weakness.

Expected behavior

URL fetching should reject loopback, link-local, private, and reserved destinations based on the actual resolved address, not only on the textual hostname. The same check should be applied to every redirect target.

Related public record

This appears related to CVE-2025-65512. The reason for filing is that the current repository version appears to remain affected and the bracketed IPv6 loopback form is a concrete bypass variant.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions