{"id":"CVE-2026-30858","aliases":["GHSA-h6gw-8f77-mmmp","GO-2026-4643"],"url":"https://o3.security/vulnerability/CVE-2026-30858","summary":"WeKnora: DNS Rebinding Vulnerability in web_fetch Tool Allows SSRF to Internal Resources","details":"### Summary\n\nA DNS rebinding vulnerability in the `web_fetch` tool allows an unauthenticated attacker to bypass URL validation and access internal resources on the server, including private IP addresses (e.g., 127.0.0.1, 192.168.x.x). By crafting a malicious domain that resolves to a public IP during validation and subsequently resolves to a private IP during execution, an attacker can access sensitive local services and potentially exfiltrate data.\n\n### Details\n\nThe vulnerability exists because the `web_fetch` tool lacks complete DNS pinning. The application performs URL validation only once via `validateParams()`, but the URL is then passed unchanged to the `fetchHTMLContent()` function, which eventually reaches `fetchWithChromedp()`. The headless browser (Chromedp) resolves the hostname independently without DNS pinning, allowing a time-of-check-time-of-use (TOCTOU) attack.\n\n**Validation phase (first DNS resolution):**\n```go\nif err := t.validateParams(p); err != nil {\n    // Returns error for private IPs\n    results[index] = &webFetchItemResult{\n        err: err,\n        // ...\n    }\n    return\n}\n```\n\n**Execution phase (second DNS resolution):**\nThe original URL (not the resolved IP) is passed through the execution chain:\n```go\noutput, data, err := t.executeFetch(ctx, p)\n// Calls fetchHTMLContent(ctx, targetURL) where targetURL is the original hostname\n```\n\n**Chromedp execution (vulnerable DNS resolution):**\n```go\nfunc (t *WebFetchTool) fetchWithChromedp(ctx context.Context, targetURL string) (string, error) {\n    // targetURL is not DNS-pinned; browser resolves it independently\n    err := chromedp.Run(ctx,\n        chromedp.Navigate(targetURL),  // Third DNS lookup occurs here\n        chromedp.WaitReady(\"body\", chromedp.ByQuery),\n        chromedp.OuterHTML(\"html\", &html),\n    )\n}\n```\n\nThe attacker controls a domain that can be configured to return different DNS responses to different queries, enabling them to bypass the initial private IP check and access restricted resources during the actual fetch.\n\n### PoC\n\n**Setup:**\n1. Deploy the DNS rebinding server (attached Python file) with the following systemd configuration:\n\n```systemd\n[Unit]\nDescription=DNS Rebinding Test Server\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=/root/Repos/dns-rebinding-server\nExecStart=/root/.proto/shims/python -u /root/Repos/dns-rebinding-server/server.py --token aleister1102 --domain aleister.ninja --port 53 --global-tracking --ip1 1.1.1.1 --ip2 0.0.0.0 --first-response-count 1 --reset-time 0\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=multi-user.target\n ```\n \n This configures the DNS server to:\n - Return `1.1.1.1` (a public IP) for the first DNS query\n - Return `127.0.0.1` (localhost) for all subsequent queries\n - TTL is set to 0 to prevent caching\n \n The sequence can also be reset via reset.domain.com (reset to 1.1.1.1).\n \n > Note: We may need to reset the sequence as the TOCTOU attack is not truly reliable and needs to be triggered multiple times.\n\n2. Set up a simple HTTP server on the localhost of the backend service:\n\n ```bash\n python -m http.server 8888\n ```\n\n3. Configure the malicious domain to point to the DNS rebinding server\n\n**Execution:**\n1. Enable web search on an agent.\n2. Prompt the agent to fetch content from the attacker-controlled domain (e.g., `http://attacker.example.com`)\n3. The sequence of events:\n   - **First DNS query** (validation phase): `attacker.example.com` → `1.1.1.1` ✓ Passes validation\n   - **Second DNS query** (execution phase): `attacker.example.com` → `127.0.0.1` ✗ Bypass achieved\n   - The `web_fetch` tool successfully connects to `127.0.0.1:8080` and returns the local server's content\n\n**Result:**\nThe attacker gains access to the local HTTP server and can read its content, demonstrating that internal resources are now accessible through the rebinding attack.\n\n<img width=\"1920\" height=\"1080\" alt=\"image\" src=\"https://github.com/user-attachments/assets/897e8494-f39e-49ce-a02a-5832bb84a73f\" />\n\nPoC video:\n\nhttps://github.com/user-attachments/assets/68daaa87-4b9b-4b6e-b6f6-ee123f5fcda9\n\n### Impact\n**Vulnerability Type:** DNS Rebinding / Server-Side Request Forgery (SSRF)\n\n**Who is impacted:**\n- Any user or agent with web search capability can exploit this vulnerability\n- The vulnerability grants access to internal services, configuration files, metadata services, and other sensitive resources normally restricted to the internal network\n- In cloud environments, this could allow access to metadata endpoints (e.g., AWS IMDSv1) to obtain credentials and secrets\\","published":"2026-03-07T16:34:28.528Z","modified":"2026-08-12T03:51:47.784480060Z","cvss":{"score":6.5,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"github.com/Tencent/WeKnora","fixedVersion":"0.3.0"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/30xxx/CVE-2026-30858.json"},{"type":"ADVISORY","url":"https://github.com/Tencent/WeKnora/security/advisories/GHSA-h6gw-8f77-mmmp"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-30858"},{"type":"PACKAGE","url":"https://github.com/Tencent/WeKnora"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:47.784480060Z"}}