Skip to content

Security: Empty target defaults to external dummy.org domain #31

@Ryderpro

Description

@Ryderpro

Security: Empty target defaults to external dummy.org domain

Originally discovered in Vite: vitejs/vite#20889

Problem

When a proxy is configured with an empty target: '', the library silently sends requests to the external domain dummy.org instead of throwing an error.

Root Cause

File: lib/http-proxy/common.ts:297

function toURL(url$3) {
    if (!url$3) url$3 = "";
    if (url$3.startsWith("//")) url$3 = `http://dummy.org${url$3}`;
    return new URL(url$3, "http://dummy.org");  // Empty string + dummy.org = dummy.org
}

Security Impact

  • Data Leakage: Cookies, tokens, and request bodies sent to unaffiliated external domain
  • Silent Failure: No error thrown to alert developers
  • Wide Impact: Affects Vite and any app using http-proxy-3 with empty targets

Evidence

  • dummy.org is a real external domain (registered 2000)
  • Currently responding with OpenResty/1.27.1.2 server
  • Verified: curl http://dummy.org returns same content as proxy responses

Reproduction

import { createProxyServer } from 'http-proxy-3';

// This should error but silently forwards to dummy.org
const proxy = createProxyServer({ target: '' });

proxy.on('proxyReq', (proxyReq) => {
    console.log('Host:', proxyReq.getHeader('host')); // Shows: dummy.org
});

Suggested Fix

Consider removing the dummy.org fallback entirely and failing fast with clear error messages:

function toURL(url$3) {
    if (!url$3) {
        throw new Error('Proxy target cannot be empty or undefined. Please provide a valid target URL.');
    }
    
    // Consider removing dummy.org fallback - it's a potential security risk
    if (url$3.startsWith("//")) {
        throw new Error('Invalid URL format. Please provide a complete URL with protocol.');
    }
    
    try {
        return new URL(url$3);
    } catch (error) {
        throw new Error(`Invalid proxy target URL: ${url$3}`);
    }
}

Alternative Approaches

  1. Minimal fix: Just validate empty targets and throw errors
  2. Safer fallback: Use example.invalid (RFC 6761 reserved domain) instead of dummy.org
  3. Warning approach: Log warnings when defaulting to dummy.org but allow it

Considerations

This would be a breaking change but could prevent configurations that are already potentially unsafe. The maintainer may prefer a different approach based on backward compatibility requirements.

Impact

This affects Vite (source) and any project using http-proxy-3 with empty targets.

Additional Context

This vulnerability affects the broader JavaScript ecosystem since:

  • Vite (major build tool) uses http-proxy-3 directly
  • Developers may unknowingly leak sensitive development data
  • The failure is silent, making it difficult to detect

References

Thank you for maintaining this library. Happy to contribute a PR if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions