How Open Notebook Prevents SSRF Attacks on AI Provider URLs Like Ollama

Open Notebook prevents Server-Side Request Forgery (SSRF) attacks by validating every AI provider URL through a strict multi-layer validation system in api/credentials_service.py that blocks dangerous IP ranges while permitting private networks for self-hosted services.

Open Notebook is an open-source knowledge management system that integrates with various AI providers including self-hosted options like Ollama and LM Studio. Because users can configure custom endpoint URLs for these providers in open_notebook/domain/credential.py, the application must protect against SSRF attacks that could target internal cloud metadata services or restricted network resources.

The SSRF Protection Architecture in Open Notebook

The core validation logic resides in api/credentials_service.py within the validate_url function. This routine implements a defense-in-depth strategy that inspects URLs before they are stored or used to make HTTP requests, ensuring that malicious actors cannot exploit credential configuration to access internal infrastructure.

Scheme Whitelisting

The first line of defense rejects any URL that does not use the standard HTTP or HTTPS protocols. The validation logic explicitly checks the URL scheme and raises a ValueError for any non-standard protocol, preventing attacks that leverage file://, ftp://, or other dangerous schemes.

Open Notebook specifically blocks link-local addresses (169.254.0.0/16) to prevent access to cloud metadata endpoints like AWS EC2's 169.254.169.254. The protection extends to IPv4-mapped IPv6 link-local addresses (e.g., ::ffff:169.254.169.254), ensuring that bypass attempts using IPv6 notation are also rejected.

DNS Resolution Inspection

When a hostname is provided rather than a raw IP address, Open Notebook uses socket.getaddrinfo to resolve the domain and inspects every returned IP address for the same link-local restrictions. Hostnames that resolve to blocked ranges are rejected, preventing DNS rebinding attacks that attempt to circumvent static IP checks.

Private Network Allowlist for Self-Hosted AI

Unlike restrictive SSRF filters that block all internal addresses, Open Notebook explicitly permits private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and localhost (127.0.0.1, ::1) to support self-hosted inference servers. This balanced approach allows developers to run local models via Ollama on port 11434 or custom ports while maintaining protection against cloud metadata exploitation.

Implementation Example: Securing Ollama Connections

The test suite in tests/test_url_validation.py demonstrates the validation policy for Ollama endpoints. The following examples show how the validate_url function handles different URL types:

from api.credentials_service import validate_url

# Allowed – Ollama running on localhost

validate_url("http://localhost:11434", "ollama")   # ✅ no exception

# Allowed – Ollama on standard loopback address

validate_url("http://127.0.0.1:11434", "ollama")   # ✅ no exception

# Allowed – Self-hosted service in private network

validate_url("http://10.0.1.5:11434", "ollama")    # ✅ no exception

# Rejected – AWS metadata endpoint (SSRF attack vector)

try:
    validate_url("http://169.254.169.254", "ollama")
except ValueError as e:
    print("Blocked:", e)   # 🚫 raises ValueError

The validation ensures that while legitimate self-hosted AI services function normally, dangerous link-local addresses that could expose cloud instance metadata are strictly prohibited.

Summary

  • Location: The SSRF protection logic lives in api/credentials_service.py inside the validate_url function.
  • Scheme enforcement: Only http and https protocols are permitted to prevent protocol-based attacks.
  • Link-local blocking: Addresses in the 169.254.x.x range and IPv4-mapped IPv6 equivalents are rejected to stop cloud metadata access.
  • DNS safety: Hostnames are resolved using socket.getaddrinfo and checked against blocked IP ranges to prevent DNS rebinding.
  • Self-hosting support: Private networks (10.x, 172.16-31.x, 192.168.x) and localhost are explicitly allowed for Ollama and similar local AI providers.

Frequently Asked Questions

How does Open Notebook differentiate between malicious SSRF targets and legitimate self-hosted AI endpoints?

Open Notebook blocks link-local addresses (169.254.x.x) that typically host cloud metadata services while explicitly allowing private RFC1918 ranges (10.x.x.x, 172.16-31.x.x, 192.168.x.x) and localhost addresses. This permits local Ollama instances on http://localhost:11434 or private network addresses while preventing access to sensitive cloud infrastructure.

What happens if I try to configure an Ollama URL with a blocked IP address?

The validate_url function in api/credentials_service.py raises a ValueError immediately upon detecting a link-local address, preventing the credential from being stored in open_notebook/domain/credential.py. The application never attempts to connect to the blocked endpoint, stopping the SSRF attack at the validation stage.

Does Open Notebook protect against DNS rebinding attacks?

Yes. When a hostname is provided rather than a raw IP, Open Notebook uses socket.getaddrinfo to resolve the hostname and inspects every returned IP address. If any resolved address falls within the blocked link-local range, the entire validation fails, preventing attackers from using DNS rebinding to bypass IP-based restrictions.

Which file contains the unit tests for URL validation?

The test suite in tests/test_url_validation.py contains assertions confirming that localhost and loopback URLs for Ollama are accepted while link-local addresses like 169.254.169.254 are rejected with a ValueError, ensuring the SSRF protection logic functions as intended.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →