Every CVE Search/ Get API key

CVE-2026-58203

NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size

5.3 MediumFix available

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
Low
Availability
Low

Exploit likelihood

0.18%Up 0.1 points since Jul 7, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.3

NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
CVE-2026-58203
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-22, CWE-59, CWE-400
Updated
2026-11-02
EUVDEUVD-2026-41878 5.3

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
EUVD-2026-41878
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-4xgf-cpjx-pc3j 5.3

pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size

Summary

NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This report does not claim network reachability by itself.

Details

NestedSecretsSettingsSource performed two passes over secrets_dir using two different, inconsistent directory-traversal implementations:

  • The size check in validate_secrets_path() used Path.glob('**/*'), which does not descend into a symbolically-linked directory.
  • The loader in load_secrets() used glob.iglob(f'{path}/**/*', recursive=True) followed by read_text(), which does follow symlinked directories and reads through the link target.

Because the two passes disagreed on symlinks, a symlinked directory inside secrets_dir whose target lives elsewhere was invisible to the size accounting (counted as 0 bytes) while still being fully read by the loader. This produces two distinct problems:

  1. Out-of-tree read (CWE-22 / CWE-59). A symlinked directory (or file) inside secrets_dir that resolves outside it is followed, and the external file's contents are loaded into the corresponding settings field.
  2. secrets_dir_max_size bypass (CWE-400). The size check never sees the out-of-tree content, so the documented size cap is neither respected nor able to reject the oversized external file. A related amplification exists for cyclic in-tree symlinks, which glob.iglob(recursive=True) re-traverses, inflating the size accounting and the number of loaded secrets.

Reproduction

In a clean Linux container, with a secrets_dir containing a symlink secrets/db -> /path/outside and an outside/passwd file of 512 bytes, while secrets_dir_max_size=100:

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,  # outside/passwd 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 affected versions, Settings().db.passwd is populated with the 512-byte out-of-tree file and no SettingsError is raised, even though the file exceeds secrets_dir_max_size.

Impact

Applications that opt into NestedSecretsSettingsSource with secrets_nested_subdir=True and load secrets from a directory whose entries can be influenced by an attacker or a lower-privileged component (for example, a writable or shared secrets mount, or a secrets directory partially populated from untrusted input) are affected. The impact is:

  • Confidentiality: files outside the configured secrets_dir can be read into settings values (local file read).
  • Integrity / availability of the safeguard: the advertised secrets_dir_max_size cap can be bypassed, and cyclic symlinks can inflate resource usage during loading.

The vulnerability requires the ability to place a symbolic link inside the configured secrets directory; it is not remotely reachable on its own. Applications that do not use NestedSecretsSettingsSource, or that point secrets_dir at a directory fully…

Record
GHSA-4xgf-cpjx-pc3j
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-22, CWE-59, CWE-400
Updated
2026-11-02
NVD 5.3

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
CVE-2026-58203
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-22, CWE-59, CWE-400
Updated
2026-11-02
OSV 5.3

NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
CVE-2026-58203
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-22, CWE-400, CWE-59
Updated
2026-11-04
OSVDEBIAN-CVE-2026-58203 5.3

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
DEBIAN-CVE-2026-58203
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Updated
2026-11-02
Show 4 moreShow less
OSVGHSA-4xgf-cpjx-pc3j 5.3

pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size

Summary

NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This report does not claim network reachability by itself.

Details

NestedSecretsSettingsSource performed two passes over secrets_dir using two different, inconsistent directory-traversal implementations:

  • The size check in validate_secrets_path() used Path.glob('**/*'), which does not descend into a symbolically-linked directory.
  • The loader in load_secrets() used glob.iglob(f'{path}/**/*', recursive=True) followed by read_text(), which does follow symlinked directories and reads through the link target.

Because the two passes disagreed on symlinks, a symlinked directory inside secrets_dir whose target lives elsewhere was invisible to the size accounting (counted as 0 bytes) while still being fully read by the loader. This produces two distinct problems:

  1. Out-of-tree read (CWE-22 / CWE-59). A symlinked directory (or file) inside secrets_dir that resolves outside it is followed, and the external file's contents are loaded into the corresponding settings field.
  2. secrets_dir_max_size bypass (CWE-400). The size check never sees the out-of-tree content, so the documented size cap is neither respected nor able to reject the oversized external file. A related amplification exists for cyclic in-tree symlinks, which glob.iglob(recursive=True) re-traverses, inflating the size accounting and the number of loaded secrets.

Reproduction

In a clean Linux container, with a secrets_dir containing a symlink secrets/db -> /path/outside and an outside/passwd file of 512 bytes, while secrets_dir_max_size=100:

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,  # outside/passwd 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 affected versions, Settings().db.passwd is populated with the 512-byte out-of-tree file and no SettingsError is raised, even though the file exceeds secrets_dir_max_size.

Impact

Applications that opt into NestedSecretsSettingsSource with secrets_nested_subdir=True and load secrets from a directory whose entries can be influenced by an attacker or a lower-privileged component (for example, a writable or shared secrets mount, or a secrets directory partially populated from untrusted input) are affected. The impact is:

  • Confidentiality: files outside the configured secrets_dir can be read into settings values (local file read).
  • Integrity / availability of the safeguard: the advertised secrets_dir_max_size cap can be bypassed, and cyclic symlinks can inflate resource usage during loading.

The vulnerability requires the ability to place a symbolic link inside the configured secrets directory; it is not remotely reachable on its own. Applications that do not use NestedSecretsSettingsSource, or that point secrets_dir at a directory fully…

Record
GHSA-4xgf-cpjx-pc3j
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-22, CWE-400, CWE-59
Updated
2026-11-02
OSVUBUNTU-CVE-2026-58203 5.3

pydantic-settings provides settings management using Pydantic. From 2.12.0 until 2.14.2, NestedSecretsSettingsSource reads secret values from files in a configured secrets_dir. When secrets_nested_subdir=True, a directory entry inside secrets_dir that is a symbolic link pointing outside secrets_dir is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented secrets_dir_max_size protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This vulnerability is fixed in 2.14.2.

Record
UBUNTU-CVE-2026-58203
CVSS 3.1
5.3 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Updated
2026-11-02
OSVMGASA-2026-0260 No score

Updated python-pydantic-settings packages fix a security vulnerability

The updated packages fix a security vulnerability: NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size. (CVE-2026-58203)

Record
MGASA-2026-0260
Updated
2026-11-02
OSVROOT-APP-PYPI-GHSA-4xgf-cpjx-pc3j No score

GHSA-4xgf-cpjx-pc3j in pydantic-settings - Patched by Root

Root has patched GHSA-4xgf-cpjx-pc3j in the pydantic-settings package for Root:PyPI. Multiple fixed versions available.

Record
ROOT-APP-PYPI-GHSA-4xgf-cpjx-pc3j
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
pydantic-settings
PyPI
2.12.0 up to 2.14.2
2.14.2
pydantic-settings
Debian:14
before 2.14.2-1, plus listed versions
2.10.1-12.10.1-22.11.0-12.12.0-12.12.0-2
Show 4 moreShow less
2.13.0-12.14.0-12.14.1-12.8.1-2
2.14.2-1
pydantic-settings
PyPI
2.12.0 up to 2.14.2, plus listed versions
2.13.02.13.12.14.02.14.1
2.14.2
python-pydantic-settings
Mageia:10
before 2.14.2-1.mga10
2.14.2-1.mga10
pydantic-settings
Root:PyPI
before 2.14.0+aikido.1
2.14.0+aikido.12.13.1+aikido.12.12.0+aikido.12.13.0+aikido.1
pydantic-settings
Ubuntu:25.10
All versions, plus listed versions
2.8.1-12.8.1-2
None known
pydantic-settings
Ubuntu:26.04:LTS
All versions, plus listed versions
2.8.1-22.12.0-22.13.0-1
None known

History

History
RecordedChangedSources
factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-58203 is a medium vulnerability (CVSS 5.3) in Pydantic Pydantic-settings, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.18%, the 8th percentile. Fixed in pydantic-settings 2.14.2.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open