CVE-2026-106439 — hydra-core
Fix: hydra-ecosystem/hydra@0dd1808CVE-2026-106439 is a CWE-470 vulnerability in hydra-core. A fix is available for hydra-core — see the affected versions and patch details below.
Hydra: Mutable instantiate policy sets allow target blocklist bypass
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-106439.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
Real-World Exposure
hydra-core🐍hydra-coreReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Summary
Hydra's legacy instantiate() target blocklists and related execution-policy
collections are stored in mutable module-level state. Because _locate() can
resolve attributes on imported objects, a configuration can resolve a mutation
method such as .discard(), modify the active policy, and then instantiate a
target that would otherwise be blocked.
Impact
A configuration controlling multiple sibling _target_ entries can first
remove an entry from a target blocklist and then invoke the removed target.
Sibling nodes are processed in insertion order and consult the same mutable
module-level policy.
This affects the legacy/default path without an execution whitelist. The 1.3 blocklist is a defense-in-depth measure rather than a complete security boundary, and applications must not treat arbitrary untrusted configuration as safe to instantiate or use for Python logging configuration.
Released hydra-core versions 1.3.4 through 1.3.6 and 1.4.0.dev4 through
1.4.0.dev9 are affected. Fixed releases are 1.3.7 and 1.4.0.dev10.
The reported direct mutation path does not bypass an execution whitelist
restricted to intended application targets and supplied by trusted Python
code. During remediation, Hydra additionally hardened generic discovery,
dispatch, introspection, alias, callable-result, and deferred-callable paths
that could otherwise undermine name-only authorization.
Technical details
In hydra-core 1.3.4 and 1.3.5, the mutable blocklist is reachable as:
hydra._internal.instantiate._instantiate2.DEFAULT_BLOCKLISTED_MODULES
In hydra-core 1.3.6, the expanded policy includes mutable collections in:
hydra._internal.target_policy
For example:
hydra._internal.target_policy.UNCONTROLLED_EXECUTION_TARGETS.discard
resolves to the bound set.discard method. The mutation target itself is not
blocked on the legacy path. Once an entry is removed, subsequent authorization
checks observe the modified set.
Other runtime policy collections can be attacked similarly by removing denied entries or adding entries to exception sets. Because the collections are module-level state, a successful mutation persists for the lifetime of the Python process unless explicitly reversed.
Safe reproduction
The behavior in hydra-core 1.3.6 can be demonstrated without invoking a shell
command. The finally block restores the modified process-global state:
from omegaconf import OmegaConf
from hydra._internal.target_policy import UNCONTROLLED_EXECUTION_TARGETS
from hydra.utils import instantiate
target = "builtins.eval"
assert target in UNCONTROLLED_EXECUTION_TARGETS
try:
result = instantiate(
OmegaConf.create(
{
"disarm": {
"_target_": (
"hydra._internal.target_policy."
"UNCONTROLLED_EXECUTION_TARGETS.discard"
),
"_args_": [target],
},
"proof": {
"_target_": target,
"_args_": ["40 + 2"],
},
}
)
)
assert result["proof"] == 42
assert target not in UNCONTROLLED_EXECUTION_TARGETS
finally:
UNCONTROLLED_EXECUTION_TARGETS.add(target)
Remediation
The fix makes runtime policy state immutable and integrity checked, and prevents declarative configuration from accessing or mutating Hydra internals and protected Python implementation state. Target authorization now covers canonical resolved identities, aliases, discovery results, callable results, deferred callables, and runtime arguments.
The patch also rejects configuration-driven code, policy, and process- environment mutation, along with unsafe introspection and formatting traversal that can expose protected runtime capabilities.
Hydra 1.3.7 receives these protections as defense in depth; it does not make untrusted configuration sandboxed. Hydra 1.4 additionally uses a trusted, narrowly scoped execution whitelist as the supported security boundary for declarative instantiation and Hydra-controlled Python logging configuration.
Users should upgrade to hydra-core 1.3.7 on the stable line or
1.4.0.dev10 on the development line.
Workarounds
Do not pass configuration from untrusted sources to instantiate() or to
Hydra-controlled Python logging configuration. The 1.3 release line has no
execution-whitelist facility, so users who cannot upgrade immediately must
restrict configuration input to trusted sources.
On affected 1.4 development releases, applications can also supply a trusted, narrowly scoped execution whitelist from Python code. The whitelist itself must not be derived from untrusted configuration.
Restart any long-running process that may already have instantiated untrusted configuration, because a policy mutation persists in process-global state.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | hydra-core | ≥ 1.3.4&&< 1.3.7 | 1.3.7pip install --upgrade 'hydra-core==1.3.7' |
| 🐍PyPI | hydra-core | ≥ 1.4.0.dev4&&< 1.4.0.dev10 | 1.4.0.dev10pip install --upgrade 'hydra-core==1.4.0.dev10' |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for hydra-core, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update hydra-core to 1.3.7 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-106439 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
An Important severity flaw was found in hydra-core, which is bundled in Red Hat AI Inference Server 3.3 and 3.4 and Red Hat Enterprise Linux AI 3.4 container images. Hydra stores the target execution policies used during object instantiation in mutable module-level state. An attacker who can supply crafted…
Avoid passing configuration from untrusted sources to Hydra's instantiate() or to Hydra-controlled Python logging configuration; restrict configuration input to trusted sources. On affected 1.4 development releases, applications can also supply a trusted, narrowly scoped execution whitelist from Python code, and the whitelist itself must not be derived from untrusted configuration. Restart any long-running process that may already have instantiated untrusted configuration, because a policy mutation persists in process-global state for the lifetime of the process. The upstream fix is available in hydra-core 1.3.7 on the stable line and 1.4.0.dev10 on the development line; for the affected…Source: Red Hat security advisory for CVE-2026-106439 (CC BY 4.0)
| Product | Fixed in | Advisory |
|---|---|---|
| Red Hat AI Inference Server 3.5 | rhaii/vllm-cuda-rhel9:1791473631 | RHSA-2026:82368 |
| Red Hat AI Inference Server 3.5 | rhaii/vllm-cpu-rhel9:1791473614 | RHSA-2026:82415 |
Frequently Asked Questions
Is CVE-2026-106439 in your dependencies?
Find it across PyPI, including transitive dependencies.