A locksmith's paperwork jam that only the building owner can trigger
polkit (formerly PolicyKit) parses XML .policy files under /usr/share/polkit-1/actions/ and /etc/polkit-1/rules.d/ to decide who can perform privileged actions. CVE-2025-7519 is a stack-style out-of-bounds write triggered when a policy XML contains 32 or more nested elements. The bug lives in polkit ≤ 0.126 and is being patched across Red Hat Enterprise Linux 6/7/8/9/10, OpenShift 4, SUSE SLE 12/15, Debian, Ubuntu, and Azure Linux 3.
The vendor score of 6.7 MEDIUM is fair on paper but the CVSS vector (AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H) tells the real story: PR:H — the attacker must already be a privileged account able to write into the polkit policy directories. Those directories are root:root 0755 by default. In other words, to exploit this you already need the exact privilege the exploit would grant you. This is a hardening/robustness fix, not a privilege escalation vector in any realistic deployment.
4 steps from start to impact.
Attacker obtains root or equivalent write access to polkit policy directories
/usr/share/polkit-1/actions/ and /etc/polkit-1/rules.d/. Both directories are root-owned and non-world-writable on every supported distro. The attacker must already have root, membership in a wheel-equivalent group with sudo NOPASSWD, or a separate privilege-escalation primitive.- Local shell
- Write access to a root-owned polkit directory
- Ability to drop or edit a .policy XML file
- If the attacker has this, they don't need polkit — they're already root
- SELinux
polkit_etc_rw_tlabels further constrain unrelated writers - Immutable-root and dm-verity images (Fedora Silverblue, CoreOS, Bottlerocket) block the write entirely
PATH rules on /etc/polkit-1/rules.d/ and /usr/share/polkit-1/actions/; FIM tools (Wazuh, Tripwire, AIDE) flag the file drop triviallyCraft a policy XML with ≥32 nested elements
.policy file whose XML tree exceeds the parser's fixed depth handling. A trivial Python one-liner or printf loop generates the payload — no dedicated exploit tool exists on GitHub as of the disclosure window.- Text editor or scripting access on target
- No public weaponized PoC in Metasploit, ExploitDB, or GitHub trending as of July 2026
Trigger polkitd to re-parse the file
polkit.service or waits for the next parse cycle to trigger the OOB write.- Ability to signal or restart polkitd, or wait for inotify
- Requires root already — restart of a system daemon is a privileged op
journalctl -u polkitAchieve crash or (theoretically) code execution as polkitd
- Successful OOB write reaches an exploitable memory region
- Modern glibc heap hardening, FORTIFY_SOURCE, stack canaries, PIE/ASLR
- Zero delta in effective privilege — no vertical movement possible
abrt, systemd-coredump, and any EDR watching SIGSEGV on init-adjacent daemonsThe supporting signals.
| In-the-wild exploitation | None observed. Not tracked by CISA KEV, GreyNoise, or Mandiant threat intel as of July 2026 |
|---|---|
| Public PoC | No weaponized PoC. Only the Red Hat Bugzilla reproducer (a nested-element XML fuzz case). No Metasploit or ExploitDB module |
| EPSS | 0.00184 (~0.18%) — bottom-percentile likelihood of exploitation in the next 30 days |
| KEV status | Not listed. No CISA action required |
| CVSS vector | AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H — local, low complexity, high privileges required, unchanged scope |
| Affected versions | polkit ≤ 0.126 on RHEL 6/7/8/9/10, OpenShift 4, SLE 12/15, openSUSE Leap 15.x, Debian, Ubuntu, Azure Linux 3, Amazon Linux 2/2023 |
| Fixed versions | See vendor backports: RHSA on polkit-0.115-x.el7_9, polkit-0.117-x.el8, polkit-0.117-x.el9; SUSE polkit-0.116-x; Debian policykit-1 0.105-33+deb12u1; upstream fix in polkit 0.127 |
| Scanner exposure data | N/A — local-only vector, no network fingerprint. Shodan/Censys/GreyNoise irrelevant |
| Disclosure date | 2025-07-14 via Red Hat Bugzilla #2379675 |
| Reporter | Red Hat Product Security internal fuzzing effort |
noisgate verdict.
The single most decisive factor is PR:H — the attacker must already hold the exact privilege the bug could grant. polkit is not a high-value-role component in the noisgate deployment-role catalog; it is a local authorization broker, not identity infrastructure, not a hypervisor, not kernel-mode, and the exploit does not cross a trust boundary.
Why this verdict
- Precondition swallows the payoff: exploiting the bug requires write access to root-owned
/etc/polkit-1/rules.d/or/usr/share/polkit-1/actions/. If an attacker has that, they are already root — the CVE grants zero additional privilege. - No exploitation signal: EPSS 0.00184, not on KEV, no public exploit code, no threat-actor reporting. The bug is a Red Hat internal fuzzing find, not an ITW discovery.
- Role multiplier: polkit runs on nearly every Linux host, but the affected role is *local authorization broker* — not identity, not hypervisor, not CA, not backup, not kernel-mode agent. Blast radius on any host is capped at 'polkitd crash' → local DoS of privilege prompts. Nothing in the noisgate high-value-role catalog applies; the floor stays at MEDIUM baseline and friction pulls it to LOW.
- Realistic worst-case is a nuisance DoS: losing polkitd breaks pkexec and desktop auth prompts — recoverable with a service restart, not a fleet event.
Why not higher?
PR:H is not marketing — the affected file paths are root-owned on every supported distro, and no known primitive turns an unprivileged user into a polkit-policy writer. Without that, the OOB write is unreachable. Nothing in the intelligence set (EPSS, KEV, PoC, ITW) contradicts this.
Why not lower?
The upstream maintainers accepted this as a security fix and every major distro shipped backports, so it is not pure hygiene — a bad admin script or a compromised config-management pipeline (Ansible/Salt/Puppet running as root) could plausibly deliver a malformed policy file and crash polkitd across a fleet. That justifies LOW rather than IGNORE.
What to do — in priority order.
- Confirm polkit policy directory permissions —
stat/etc/polkit-1/rules.d/and/usr/share/polkit-1/actions/— both should beroot:root 0755. Any deviation is the real finding, not the CVE itself. No mitigation SLA for LOW; verify during your next hardening pass. - Add FIM rules on polkit policy paths — Wazuh, Tripwire, AIDE, or auditd
-w /etc/polkit-1/rules.d/ -p wa -k polkit_policywill flag any policy file drop. This catches both this CVE and the far scarier scenario of an attacker installing a *legitimate* malicious policy. Roll into normal detection engineering backlog. - Patch during next monthly maintenance window — Pull the vendor backport (RHSA/SUSE/Debian/Ubuntu) via
dnf update polkit/apt upgrade policykit-1/zypper up polkit. LOW verdict = no mitigation SLA; slot into the 365-day remediation window, prioritized behind any HIGH/CRITICAL work. - Audit config-management pipelines for polkit file writes — Ansible/Salt/Puppet/Chef roles that template
.policyfiles are the only realistic delivery vector for a malformed XML. Add a schema/depth lint to CI to reject nested-element counts >16 before the file ever lands on production.
- Network segmentation / firewalls — the vector is local (AV:L). Perimeter controls are irrelevant.
- Disabling polkit — polkit is on the critical path for pkexec, systemd unit auth, NetworkManager, and desktop privilege prompts. Turning it off breaks admin workflows without meaningfully reducing attack surface.
- EDR behavioral rules on pkexec — polkit's CLI helper is not involved in this bug; watching pkexec catches Pwnkit-class issues, not policy-file parser bugs.
Crowdsourced verification payload.
Run on each Linux host as any user (root not required for version check). Invoke: bash check-cve-2025-7519.sh. Compares installed polkit version against the distro's fixed baseline and inspects policy-dir permissions.
#!/usr/bin/env bash
# noisgate: CVE-2025-7519 polkit OOB write check
# Exit 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
VERDICT="UNKNOWN"
REASON=""
if ! command -v pkaction >/dev/null 2>&1 && ! command -v pkexec >/dev/null 2>&1; then
echo "UNKNOWN: polkit not installed"
exit 2
fi
# Detect package manager and installed version
if command -v rpm >/dev/null 2>&1; then
PKG_VER=$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' polkit 2>/dev/null || rpm -q --qf '%{VERSION}-%{RELEASE}\n' polkit-libs 2>/dev/null)
DISTRO="rpm"
elif command -v dpkg >/dev/null 2>&1; then
PKG_VER=$(dpkg-query -W -f='${Version}\n' policykit-1 2>/dev/null || dpkg-query -W -f='${Version}\n' polkitd 2>/dev/null)
DISTRO="deb"
else
echo "UNKNOWN: no supported package manager"
exit 2
fi
if [ -z "${PKG_VER:-}" ]; then
echo "UNKNOWN: could not resolve polkit package version"
exit 2
fi
echo "Installed polkit: $PKG_VER ($DISTRO)"
# Upstream fixed in 0.127. Vendor backports differ; consult errata.
UPSTREAM_VER=$(echo "$PKG_VER" | grep -oE '^[0-9]+\.[0-9]+' | head -1)
if [ -n "$UPSTREAM_VER" ]; then
MAJ=${UPSTREAM_VER%.*}; MIN=${UPSTREAM_VER#*.}
if [ "$MAJ" -eq 0 ] && [ "$MIN" -lt 127 ]; then
# Check for vendor backport marker in changelog
if [ "$DISTRO" = "rpm" ] && rpm -q --changelog polkit 2>/dev/null | grep -q "CVE-2025-7519"; then
VERDICT="PATCHED"
REASON="vendor backport present in RPM changelog"
elif [ "$DISTRO" = "deb" ] && zcat -f /usr/share/doc/policykit-1/changelog.Debian.gz 2>/dev/null | grep -q "CVE-2025-7519"; then
VERDICT="PATCHED"
REASON="vendor backport present in Debian changelog"
else
VERDICT="VULNERABLE"
REASON="polkit ${UPSTREAM_VER} < 0.127 and no CVE-2025-7519 backport marker found"
fi
else
VERDICT="PATCHED"
REASON="polkit ${UPSTREAM_VER} >= 0.127"
fi
fi
# Sanity: policy directory permissions
for d in /etc/polkit-1/rules.d /usr/share/polkit-1/actions; do
if [ -d "$d" ]; then
PERM=$(stat -c '%U:%G %a' "$d")
echo "Policy dir $d -> $PERM"
fi
done
echo "$VERDICT: $REASON"
case "$VERDICT" in
PATCHED) exit 0 ;;
VULNERABLE) exit 1 ;;
*) exit 2 ;;
esac
If you remember one thing.
dnf/apt/zypper update polkit) into your normal monthly patch train behind anything HIGH or CRITICAL. Bigger win: add auditd/FIM on /etc/polkit-1/rules.d/ and /usr/share/polkit-1/actions/ so you'll catch the *real* threat — an attacker installing a legitimate malicious policy file, which has always been game over regardless of this CVE.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.