This is a burglar slipping a master key to a trusted janitor and having them open the vault
CVE-2026-23268 is an AppArmor policy-management flaw in the Linux kernel that lets an unprivileged local user open AppArmor control files in apparmorfs and then abuse a *confused deputy* pattern to get a privileged process to perform the write. Upstream Linux marked kernels from 4.11 onward as affected until the fix landed; the CVE record maps fixed upstream lines at 5.10.253, 5.15.203, 6.1.169, 6.6.130, 6.12.77, 6.18.18, 6.19.8, and 7.0, with distro backports varying by vendor.
The vendor HIGH 7.8 score is technically defensible in a lab because full policy manipulation can remove confinement, trigger denial of service, bypass user-namespace restrictions, and enable follow-on local privilege escalation. In real enterprise operations, though, the severity is lower because the attacker already needs code execution as a local user *and* needs a privileged target process they can influence into writing to the opened AppArmor interface; that extra dependency materially narrows the reachable population compared with a clean one-shot LPE.
4 steps from start to impact.
Gain local code execution on a Linux host
- Local execution as a non-root user
- Host runs an affected Linux kernel with AppArmor integrated
- AppArmor interfaces are present and reachable on the host
- Requires prior compromise or legitimate user access
- Purely remote perimeter attackers cannot trigger this directly
- Many enterprises already have EDR and PAM controls that make persistent local footholds noisy
386714 for CrackArmor and recommends QID 45097 to inventory the running kernel.Open the AppArmor policy interface
.load, .replace, or .remove. The attacker's own write should still be blocked later, so the opened file descriptor becomes the object they must smuggle to a more privileged process.- AppArmor policy-management files exist under
/sys/kernel/security/apparmor/ - The attacker can open the interface before policy enforcement on the write path is re-evaluated
- If AppArmor is disabled or not mounted, this path may not be usable
- Some hardened environments reduce available helper processes and IPC channels
/sys/kernel/security/apparmor/.load, .replace, or .remove is the right detection surface.Pass the file descriptor to a privileged helper
sudo and Postfix/sendmail, which is the practical difference between an interesting bug and a broadly reliable exploit.- A privileged process exists that can be manipulated to write attacker-controlled data
- The environment permits descriptor passing or equivalent helper abuse
- The specific local chain works against the distro's userland and policy mix
- This is the decisive brake on severity: exploitation is not self-contained
- Requires a suitable privileged target and a workable interaction path
- Modern hardening, constrained sudo rules, and service isolation break many real-world chains
Rewrite policy to drop confinement or set up follow-on LPE
sudo/Postfix interactions or other AppArmor bugs to reach root.- Successful privileged write into AppArmor policy interface
- Target services rely on AppArmor confinement for security boundaries
- Impact is strongest on AppArmor-dependent distros and hosts using confinement meaningfully
- Turning policy control into root may still require a second-stage primitive or environment-specific chain
/sys/kernel/security/apparmor/ plus AppArmor audit logs.The supporting signals.
| In-the-wild status | No authoritative public evidence of active exploitation found as of 2026-05-30. CISA KEV does not list CVE-2026-23268. |
|---|---|
| PoC availability | Qualys states it developed working PoCs and a full exploitation chain during coordinated disclosure, but public exploit code appears withheld. I did not find a credible public GitHub PoC for this CVE specifically. |
| EPSS | 0.00021 (0.0616 percentile in the CVE record enrichment), which is extremely low and consistent with a niche post-compromise local path rather than broad internet-scale abuse. |
| KEV status | Not KEV-listed. For defenders, that removes the strongest external signal that this is already getting operationalized at scale. |
| CVSS meaning | AV:L/AC:L/PR:L/UI:N means local, low-complexity, low-privilege, no-user-interaction; the score captures severe host impact, but it does not capture the real-world helper-process dependency well. |
| Affected versions | Upstream Linux marks versions from 4.11 onward as affected until the fixed branches: <5.10.253, <5.15.203, <6.1.169, <6.6.130, <6.12.77, <6.18.18, <6.19.8, or <7.0 depending on branch. |
| Fixed versions | Upstream fixed baselines are 5.10.253 / 5.15.203 / 6.1.169 / 6.6.130 / 6.12.77 / 6.18.18 / 6.19.8 / 7.0. Distro backports matter more than raw uname -r on Ubuntu, SUSE, and other enterprise kernels. |
| Distro backport reality | Ubuntu tracks the CVE directly and SUSE shows broad kernel-package impact with released or in-progress fixes across multiple SLE tracks; Amazon Linux 2023 reports Not Affected for kernel6.18 on its advisory page. |
| Scanning and exposure data | This is not meaningfully internet-scannable like an HTTP RCE. The right exposure lens is CMDB/kernel inventory plus host telemetry; Qualys published dedicated detection coverage instead of perimeter scanning guidance. *Inference:* Shodan/Censys-style counts are poor prioritization inputs for this CVE. |
| Disclosure and attribution | Published on 2026-03-18. Public research and branding came from Qualys Threat Research Unit under the CrackArmor umbrella. |
noisgate verdict.
The single biggest severity brake is that exploitation is not self-contained: the attacker already needs local code execution and then must coerce a privileged process into writing through the opened AppArmor file descriptor. That makes this a real but narrower post-initial-access host escalation/control-bypass issue, not a perimeter-breaker or broadly wormable event.
Why this verdict
- Downgrade for attacker position: this starts at
AV:LwithPR:L, which means the attacker is already on the box. That implies prior compromise, stolen credentials, or an exposed multi-user/container environment before this CVE adds value. - Downgrade for chain dependency: the vulnerable user cannot simply write policy and win; they need a manipulable privileged process to perform the write. That helper-process requirement is real operational friction and cuts exploit reliability hard.
- Keep it above LOW because blast radius is host-level: if the chain works, the attacker can rewrite AppArmor policy, remove confinement, trigger service DoS, bypass user-namespace restrictions, and set up follow-on root paths. On Ubuntu/Debian/SUSE fleets that rely on AppArmor, the impact on a compromised host is severe.
- Downgrade for threat intel: no KEV listing, no public active exploitation evidence, and an EPSS of
0.00021all argue against treating this like an emergency internet-wide exploitation event. - Limit reachable population: AppArmor is common, but successful exploitation still concentrates in environments with local users, shared compute, CI runners, developer boxes, bastions, or container hosts where an attacker can land and then interact with a privileged helper.
Why not higher?
This is not unauthenticated remote, not broadly reachable over the network, and not a clean one-step LPE. The extra requirement for a privileged helper process means many hosts will be theoretically affected but not practically exploitable on demand. Without KEV pressure or public exploitation at scale, HIGH overstates the fleet-wide urgency.
Why not lower?
Once the chain lands, the attacker gets effective control over AppArmor policy, which is a foundational host security boundary on affected distros. That is enough to strip confinement, break namespace restrictions, and support follow-on root or destructive actions, so this is more than backlog hygiene.
What to do — in priority order.
- Monitor AppArmor control-file writes — Add host telemetry for unexpected access to
/sys/kernel/security/apparmor/.load,.replace, and.remove, and alert on profile load/replace/remove activity from unusual parent processes. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but this control is still worth deploying first on shared Linux estates, CI runners, bastions, and container nodes. - Constrain privileged helper paths — Review
sudorules, local MTA usage, and any service workflows that let low-privilege users influence root-owned helper processes or pass attacker-controlled content into them. Do this during the normal remediation cycle and prioritize multi-user systems where a confused-deputy chain is most plausible. - Reduce untrusted local tenancy — Prioritize affected hosts that permit shell access for many users, run build agents, or host rootless containers; those are the places where a local foothold is easiest to obtain and reuse. For MEDIUM, fold tenancy reduction into your regular hardening program while scheduling the vendor kernel fix inside the 365-day window.
- Inventory by running kernel, not package name alone — Use VM/CMDB tooling or EDR to capture the running kernel plus distro advisory status, because distro backports can make
uname -rmisleading. This is the quickest way to separate exposed Ubuntu/SUSE nodes from unaffected tracks such as Amazon Linux entries marked not affected.
- A perimeter firewall or WAF does nothing here because the exploit path is local and host-resident.
- MFA does not mitigate the bug itself; it may reduce initial access, but once an attacker already has a local user context, MFA is out of band.
- Changing only file permissions on the AppArmor interface is not the upstream fix; the kernel notes non-root processes legitimately need policy loads in some namespaces, so the issue is the privilege-check design, not just mode bits.
Crowdsourced verification payload.
Run this on the target Linux host as root or with sudo so it can inspect AppArmor state; invoke it as sudo bash ./check-cve-2026-23268.sh. It is a triage script, not a definitive vendor-backport oracle: it prints VULNERABLE, PATCHED, or UNKNOWN based on AppArmor presence and upstream fixed version floors.
#!/usr/bin/env bash
# check-cve-2026-23268.sh
# Triages exposure to CVE-2026-23268 on a Linux host.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
APPARMOR_FS="/sys/kernel/security/apparmor"
RUNNING_KERNEL="$(uname -r)"
BASE_KERNEL="${RUNNING_KERNEL%%-*}"
have_cmd() { command -v "$1" >/dev/null 2>&1; }
version_ge() {
# returns 0 if $1 >= $2
printf '%s\n%s\n' "$2" "$1" | sort -V -C
}
version_lt() {
! version_ge "$1" "$2"
}
major="$(echo "$BASE_KERNEL" | cut -d. -f1)"
minor="$(echo "$BASE_KERNEL" | cut -d. -f2)"
patch="$(echo "$BASE_KERNEL" | cut -d. -f3)"
# AppArmor presence / state
if [[ ! -d "$APPARMOR_FS" ]]; then
echo "UNKNOWN - AppArmor filesystem not present at $APPARMOR_FS; cannot confirm runtime exposure"
exit 2
fi
if [[ -r /sys/module/apparmor/parameters/enabled ]]; then
aa_enabled="$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null || true)"
if [[ "$aa_enabled" != "Y" ]]; then
echo "UNKNOWN - AppArmor kernel module not enabled at runtime"
exit 2
fi
fi
# Distro hint output (informational only)
distro="unknown"
if [[ -r /etc/os-release ]]; then
. /etc/os-release
distro="${PRETTY_NAME:-unknown}"
fi
# Upstream fixed floors from the CVE record
status="UNKNOWN"
reason="Kernel branch not recognized or may rely on distro backport"
if [[ "$major" -lt 4 ]]; then
status="PATCHED"
reason="Kernel older than 4.11 is outside upstream affected range"
elif [[ "$major" -eq 4 ]]; then
if [[ "$minor" -lt 11 ]]; then
status="PATCHED"
reason="Kernel older than 4.11 is outside upstream affected range"
else
status="UNKNOWN"
reason="4.x branch is affected upstream from 4.11; enterprise backport status must be checked via vendor advisory"
fi
elif [[ "$major" -eq 5 ]]; then
if [[ "$minor" -eq 10 ]]; then
if version_ge "$BASE_KERNEL" "5.10.253"; then status="PATCHED"; reason="At or above upstream fixed floor 5.10.253"; else status="VULNERABLE"; reason="Below upstream fixed floor 5.10.253"; fi
elif [[ "$minor" -eq 15 ]]; then
if version_ge "$BASE_KERNEL" "5.15.203"; then status="PATCHED"; reason="At or above upstream fixed floor 5.15.203"; else status="VULNERABLE"; reason="Below upstream fixed floor 5.15.203"; fi
else
status="UNKNOWN"
reason="5.x branch not directly mapped here; check distro backport advisory"
fi
elif [[ "$major" -eq 6 ]]; then
case "$minor" in
1)
if version_ge "$BASE_KERNEL" "6.1.169"; then status="PATCHED"; reason="At or above upstream fixed floor 6.1.169"; else status="VULNERABLE"; reason="Below upstream fixed floor 6.1.169"; fi ;;
6)
if version_ge "$BASE_KERNEL" "6.6.130"; then status="PATCHED"; reason="At or above upstream fixed floor 6.6.130"; else status="VULNERABLE"; reason="Below upstream fixed floor 6.6.130"; fi ;;
12)
if version_ge "$BASE_KERNEL" "6.12.77"; then status="PATCHED"; reason="At or above upstream fixed floor 6.12.77"; else status="VULNERABLE"; reason="Below upstream fixed floor 6.12.77"; fi ;;
18)
if version_ge "$BASE_KERNEL" "6.18.18"; then status="PATCHED"; reason="At or above upstream fixed floor 6.18.18"; else status="VULNERABLE"; reason="Below upstream fixed floor 6.18.18"; fi ;;
19)
if version_ge "$BASE_KERNEL" "6.19.8"; then status="PATCHED"; reason="At or above upstream fixed floor 6.19.8"; else status="VULNERABLE"; reason="Below upstream fixed floor 6.19.8"; fi ;;
*)
status="UNKNOWN"
reason="6.x branch not directly mapped here; check distro backport advisory" ;;
esac
elif [[ "$major" -ge 7 ]]; then
if version_ge "$BASE_KERNEL" "7.0.0"; then
status="PATCHED"
reason="Upstream original fix is present in 7.0+"
else
status="UNKNOWN"
reason="Unable to classify 7.x prerelease/custom branch safely"
fi
fi
echo "$status - distro=$distro running_kernel=$RUNNING_KERNEL base_kernel=$BASE_KERNEL apparmor_fs=$APPARMOR_FS reason=$reason"
case "$status" in
PATCHED) exit 0 ;;
VULNERABLE) exit 1 ;;
*) exit 2 ;;
esac
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.