---
id: "GHSA-955g-x97g-8mcp"
page: "https://infrastack.ai/live/GHSA-955g-x97g-8mcp"
kind: "vulnerability"
aliases: ["GHSA-955g-x97g-8mcp"]
title: "Quadratic time and memory multi-host URL validation"
severity: "medium"
cvss: 6.3
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "pydantic", "note": "2.0.0,<2.14.0", "fixed": ["2.14.0"], "affected": ">= 2.0.0, < 2.14.0", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["cwe-407", "fastapi", "package", "pydantic", "python", "web-api"]
not_affected_if: ["no-multihost-url-fields", "trusted-input-only"]
published_at: "2026-10-29T17:06:46+00:00"
first_seen_at: "2026-11-09T22:53:21+00:00"
updated_at: "2026-11-09T22:54:53+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/pydantic/pydantic/security/advisories/GHSA-955g-x97g-8mcp", "first_seen_at": "2026-11-09T22:53:21+00:00"}]
exploit_sources: []
---

# Quadratic time and memory multi-host URL validation

Link for people: https://infrastack.ai/live/GHSA-955g-x97g-8mcp (this .md is for agents)

Pydantic's multi-host URL validation parses the whole URL prefix once per host, so a long scheme with many hosts makes time and memory grow quadratically. An attacker who can submit a roughly 100 KB string to a PostgresDsn, MongoDsn or NatsDsn field can exhaust a server's memory and stall it, a denial of service.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- pypi:pydantic affected >= 2.0.0, < 2.14.0 fixed 2.14.0

## How to check

- Check the installed version with `pip show pydantic` or `python -c "import pydantic; print(pydantic.VERSION)"`.
- Search the code for `PostgresDsn`, `MongoDsn`, `NatsDsn` or custom types built on `MultiHostUrl` that validate untrusted input.

## Fix

- `pydantic` `2.14.0` or later (fixed in 2.14.0; affected from 2.0.0 up to but not including 2.14.0).

## Timeline

- 2026-11-09T22:53:21+00:00 ghsa-repo https://github.com/pydantic/pydantic/security/advisories/GHSA-955g-x97g-8mcp

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/pydantic/pydantic/security/advisories/GHSA-955g-x97g-8mcp

## From the sources

### Summary

Validating an untrusted URL with a long scheme and many hosts into a multi-host URL field (e.g. [`PostgresDsn`](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/#pydantic.networks.PostgresDsn)) takes quadratic time and memory: an input of about a hundred kilobytes takes around a gigabyte of memory to validate.

### Details

The [`parse_multihost_url()`](https://github.com/pydantic/pydantic/blob/v2.13.5/pydantic-core/src/validators/url.rs#L537) function (in [`pydantic-core/src/validators/url.rs`](https://github.com/pydantic/pydantic/blob/v2.13.5/pydantic-core/src/validators/url.rs)) parses each host separately, prepending the whole URL prefix (including the scheme) to every one of them ([L644-L649](https://github.com/pydantic/pydantic/blob/v2.13.5/pydantic-core/src/validators/url.rs#L644-L649)):

```rust
let extra_urls: Vec<Url> = hosts
    .iter()
    .map(|host| {
        let reconstructed_url = format!("{prefix}{host}");
        parse_url(&reconstructed_url, input, strict)
    })
    .collect::<ValResult<_>>()?;
```

As the scheme can be arbitrarily long, and is parsed and stored once per host, both time and memory grow quadratically with the input size. Allowed schemes (e.g. `postgres` for `PostgresDsn`) are only checked after parsing, so they don't prevent the issue.

The issue was fixed in commit https://github.com/pydantic/pydantic/commit/b4028f9d87e34750e53be0ba011d70f3c0fcc94e.

### Impact

Denial of service through validation of untrusted input. Affected are applications validating untrusted strings into multi-host URL fields ([`PostgresDsn`](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/#pydantic.networks.PostgresDsn), [`MongoDsn`](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/#pydantic.networks.MongoDsn), [`NatsDsn`](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/#pydantic.networks.NatsDsn), or custom types built on `MultiHostUrl`).

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
