Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

@waleedlatif1 waleedlatif1 commented Dec 11, 2025

Summary

  • fix dns rebinding/ssrf vulnerability

courteously pointed out by https://github.com/aydinnyunus/

Type of Change

  • Other: Security

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Dec 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
docs Skipped Skipped Dec 11, 2025 9:08pm

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 11, 2025

Greptile Overview

Greptile Summary

This PR fixes a DNS rebinding/SSRF vulnerability in the proxy and file parsing APIs by implementing DNS pinning.

Key changes:

  • Added validateUrlWithDNS() function that resolves hostnames to IP addresses before making requests and validates that resolved IPs are not private/reserved
  • Added createPinnedUrl() helper that substitutes the hostname with the resolved IP address
  • Updated /api/proxy and /api/files/parse routes to use DNS-pinned URLs with the original hostname in the Host header
  • Added comprehensive private/reserved IP blocking including IPv4/IPv6 loopback, private ranges (10.x, 172.16-31.x, 192.168.x), link-local (169.254.x), carrier-grade NAT (100.64-127.x), and test networks

Security improvement:
The previous implementation validated URLs before fetching but was vulnerable to DNS rebinding attacks where an attacker could:

  1. Set up a domain that initially resolves to a public IP (passes validation)
  2. Have the DNS TTL expire between validation and fetch
  3. Have the second DNS lookup resolve to a private IP (bypasses validation)

The new implementation resolves DNS once during validation, then uses the resolved IP directly in the fetch request, eliminating the time-of-check-to-time-of-use (TOCTOU) vulnerability.

Confidence Score: 5/5

  • This PR is safe to merge - it's a security improvement with comprehensive test coverage and no functional regressions.
  • Score reflects: 1) Well-implemented security fix addressing a real SSRF vulnerability, 2) Comprehensive private IP blocking patterns, 3) Good test coverage for the new functions, 4) Clean implementation using DNS pinning with Host header preservation, 5) No breaking changes to existing functionality.
  • No files require special attention - all changes are well-implemented security improvements.

Important Files Changed

File Analysis

Filename Score Overview
apps/sim/lib/core/security/input-validation.ts 5/5 Added validateUrlWithDNS function for DNS-pinned URL validation and createPinnedUrl helper to prevent DNS rebinding/SSRF attacks. Comprehensive IP blocking including IPv4/IPv6 private ranges, loopback, link-local, and carrier-grade NAT.
apps/sim/lib/core/security/input-validation.test.ts 5/5 Added comprehensive test coverage for validateUrlWithDNS and createPinnedUrl functions covering basic validation, DNS resolution, private IP rejection, and URL pinning.
apps/sim/app/api/proxy/route.ts 5/5 Updated to use validateUrlWithDNS with DNS pinning, replacing validateProxyUrl. Fetch now uses pinned IP with Host header to prevent DNS rebinding attacks.
apps/sim/app/api/files/parse/route.ts 5/5 Updated handleExternalUrl to use validateUrlWithDNS with DNS pinning, replacing validateExternalUrl. Fetch now uses pinned IP with Host header to prevent DNS rebinding attacks.

Sequence Diagram

sequenceDiagram
    participant Client
    participant ProxyAPI as Proxy API
    participant Validation as validateUrlWithDNS
    participant DNS as DNS Server
    participant External as External Server

    Client->>ProxyAPI: GET /api/proxy?url=https://example.com
    ProxyAPI->>Validation: validateUrlWithDNS(url)
    Validation->>Validation: Basic URL validation (protocol, format)
    Validation->>DNS: dns.lookup(hostname)
    DNS-->>Validation: resolved IP (e.g., 93.184.216.34)
    Validation->>Validation: Check if IP is private/reserved
    alt IP is private/reserved
        Validation-->>ProxyAPI: { isValid: false, error: "blocked IP" }
        ProxyAPI-->>Client: 403 Forbidden
    else IP is public
        Validation-->>ProxyAPI: { isValid: true, resolvedIP, originalHostname }
        ProxyAPI->>ProxyAPI: createPinnedUrl(url, resolvedIP)
        ProxyAPI->>External: fetch(https://93.184.216.34/path, { headers: { Host: "example.com" }})
        External-->>ProxyAPI: Response
        ProxyAPI-->>Client: Proxied response
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@waleedlatif1 waleedlatif1 merged commit b595273 into staging Dec 11, 2025
9 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/vuln branch December 11, 2025 21:42
Sign up for free to 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.

2 participants