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

> Open Notebook stops SSRF attacks on AI provider URLs like Ollama. Our multi-layer validation blocks dangerous IPs while allowing private networks for self-hosted services.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-27

---

**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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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.

### Link-Local Address Blocking

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`](https://github.com/lfnovo/open-notebook/blob/main/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:

```python
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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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.