Security

Two Critical Vulnerabilities This Week: nginx RCE (CVE-2026-42945) and Fragnesia Kernel LPE (CVE-2026-46300)

May 13, 2026

Back to Blog
Action required: If you operate nginx anywhere, upgrade to 1.31.0 immediately. A public proof-of-concept exploit is circulating as of May 13. Automated scanners are already indexing vulnerable endpoints.

Panelica operators: nginx 1.31.0 packages are live in the stable channel. Go to Update Center, select the nginx and nginx-panel packages, and click Apply now. Two-second panel interruption, then automatic reconnect. No maintenance window needed.

The Week's Threat Landscape

Two independent disclosures landed on the same day this week, both targeting infrastructure that every Linux-based hosting server runs. On May 13, 2026, F5 published a coordinated advisory for CVE-2026-42945, a heap buffer overflow in nginx affecting versions spanning 18 years of the codebase. Hours later, V12, openSUSE, CloudLinux, and AlmaLinux pushed emergency kernel patches for CVE-2026-46300 (Fragnesia), a local privilege escalation rooted in the IPsec ESP-in-TCP subsystem. Neither vulnerability is related to the other at a code level. But for a server operator running a hosting panel, they arrived at the same time, requiring two separate responses in parallel. This post covers both in technical depth, then examines how Panelica's isolation architecture changes the blast radius calculation for each.

Note: If you read our earlier post on CVE-2026-43284 (Dirty Frag), Fragnesia is the third member of that family. We explain the lineage below.


CVE-2026-42945: nginx Heap Buffer Overflow Leading to Remote Code Execution

The Vulnerability Pattern

The bug lives inside nginx's rewrite engine. Specifically, it involves the interaction between three directive types: rewrite with capture groups ($1, $2, etc.), a set directive that includes a literal question mark in the replacement string, and a subsequent chained if or rewrite directive that inherits the rewrite context.

Here is the minimal trigger pattern (for reference only):

location /api/ {
    rewrite ^/api/(.+)$ /index.php?route=$1 last;

    if ($request_method = POST) {
        set $args "${args}&method=post";
        rewrite ^ $uri? last;
    }
}

This pattern is common in legacy Laravel, Symfony, and custom PHP framework deployments that predate clean URL conventions.

Technical Root Cause

The root cause is in ngx_http_script_start_args_code. When this function executes, it sets the e->is_args = 1 flag on the script engine state. The flag is never cleared during the lifetime of a rewrite chain. A subsequent set directive calculates its output buffer size using the raw byte length of the replacement string. But at write time, the main engine checks is_args = 1 and runs the output through ngx_escape_uri in NGX_ESCAPE_ARGS mode. In this mode, every +, %, and & character expands from 1 byte to 3 bytes (percent-encoding). The buffer was sized for the unexpanded string. The write overflows it.

The result is a heap buffer overflow in the nginx worker process context. On systems with weak or disabled ASLR, this is exploitable for remote code execution running as the nginx worker user. On hardened systems, the worst-case outcome is a worker process crash, which in multi-worker configurations means a service interruption rather than full DoS, but single-worker deployments go offline entirely.

Scope and Affected Versions

This is not a recent regression. The affected code path traces back to nginx 0.6.27, released in 2008. Every nginx version from 0.6.27 through 1.30.0 is affected. The 1.31.0 release published May 13, 2026 contains the fix. The commercial scope is broader:

  • NGINX Plus R32 through R36
  • NGINX Instance Manager 2.16.0 through 2.21.1
  • F5 WAF for NGINX 5.9.0 through 5.12.1

Discovery credit goes to the depthfirst team, who found the issue during an April 2026 autonomous codebase scan. F5 confirmed the report on April 24. The coordinated advisory was published May 13 alongside the patch.

CVSS Scores

  • CVSS 4.0: 9.2 (Critical) -- network-accessible, no authentication, low complexity, high impact on confidentiality and integrity
  • CVSS 3.1: 8.1 (High) -- scored lower due to the ASLR mitigation factoring into exploitability

Where Panelica Stands: A Grep-Verified Exposure Map

Panelica ships two nginx instances: one for the panel itself (port 8443) and one for customer virtual hosts (ports 80 and 443). Both live inside /opt/panelica/services/nginx-*/, fully isolated from any system nginx installation. The question is whether any auto-generated configuration activates the vulnerable rewrite pattern. The answer differs by code path.

Location Vulnerable pattern? Evidence
etc/templates/nginx/vhost.tpl (domain provisioning template) No No rewrite directive present in the template at all
services/nginx-panel/conf/nginx.conf and services/nginx-customer/conf/nginx.conf No Core configs contain no rewrite directives
etc/nginx-customer/snippets.d/* (system hardening snippets) No HSTS, CSP, and DDoS-mitigation snippets use no capture groups or set with query marks
etc/nginx-customer/vhosts.d/* (generated customer vhosts) No Generated vhost blocks do not include rewrite directives
Backend Go runtime config generation No Code search across all config generators finds no rewrite.*$N emission
htaccess converter (backend/internal/services/migration/htaccess_converter.go) Potential yes This code translates cPanel/Plesk .htaccess files into nginx syntax. The converter includes commented example handling for patterns like RewriteRule ^(.*)$ index.php?q=$1 [L,QSA], which it outputs as rewrite ^(.*)$ /index.php?q=$1 last; -- precisely the trigger pattern for CVE-2026-42945. Migration users who imported WordPress, Laravel, or legacy PHP sites from cPanel or Plesk may have this pattern active in their vhosts.
Custom nginx snippets via panel UI (NginxSnippetService, backend/internal/services/config/nginx_snippet_service.go) Potential yes NginxSnippetService accepts operator- and customer-written nginx blocks, validates them with nginx -t, and writes them live. A syntactically valid but vulnerable rewrite block passes validation and goes active. The service does not pattern-scan for CVE-specific directive combinations.

The bottom line: A vanilla Panelica installation -- no migration history, no manual rewrite snippets -- does not expose this CVE. The attack surface is real for two specific groups: operators who ran a cPanel or Plesk migration that imported WordPress or legacy PHP .htaccess rewrites, and operators or customers who manually wrote nginx snippet blocks containing the trigger pattern. Even in those cases, Panelica's isolation architecture significantly reduces what an attacker can do after gaining the nginx worker's code execution context.


Why 18 Years and an AI

The bug introduced in nginx 0.6.27 (released December 2008) survived without discovery for 18 years. Understanding why that happened, and what changed in April 2026, matters for anyone thinking about long-term infrastructure security posture.

The root cause is not obscure. The is_args flag in the script engine state, the buffer sizing logic in the set directive handler, and the escape expansion in the args encoding path are each individually readable. The bug only becomes visible when you trace the state machine across all three components simultaneously -- a pattern that does not surface in normal code review, unit testing, or fuzzing against single directives. The combination of capture groups, a set directive with a question mark, and a subsequent rewrite that inherits the rewrite context is a fairly specific multi-directive interaction. It reads fine in isolation. It overflows in combination.

For comparison: Shellshock (bash, 1989) survived 25 years. Dirty COW (kernel, 2007) survived 9 years. Log4Shell (Log4j, 2013) survived 8 years. Heartbleed (OpenSSL, 2012) survived 2 years. Dirty Pipe (kernel, 2020) survived 2 years. Long-lived bugs in widely-deployed open-source software are the rule, not the exception.

What changed in 2026 is the discovery mechanism. depthfirst is an autonomous vulnerability analysis platform that uses AI-driven static analysis to trace cross-component state interactions at scale. The tool does not read files in isolation -- it builds a model of how data flows between modules and flags cases where state assumptions made in one function are violated by side effects in another. That is exactly the class of bug that the nginx rewrite engine contained. The April 2026 scan identified the pattern, depthfirst reported it to F5 on April 24, and F5 published the fix 19 days later.

The implication for operators is straightforward: the open-source "many eyes" model has limits when the bug requires reasoning across multiple files, multiple directives, and multiple runtime states simultaneously. AI-based codebase analysis is beginning to close that gap. Expect more 18-year bugs to surface in coming months -- in nginx, in other web servers, in kernel subsystems, in language runtimes. The tooling to find them now exists and is being deployed at scale.

The practical lesson: patch velocity matters, but it is no longer sufficient on its own. Isolation, least-privilege, and containment architecture are the difference between "a bug was found and patched" and "a bug was found, exploited, and we lost 200 customer sites." Panelica was built on this assumption from day one.


What an RCE on www-data Actually Means

Remote code execution via CVE-2026-42945 lands an attacker inside the nginx worker process, running as www-data (or the equivalent unprivileged user your distribution uses for nginx workers). That is not root. But it is not harmless either. Understanding what that context can and cannot reach is what separates a useful security posture from a false sense of safety.

What www-data can access on an unisolated server:

  • All files in all web roots served by that nginx instance -- read and write
  • Any .env, wp-config.php, or application config file that lives in a web root or is readable by www-data
  • Database credentials stored in those config files, giving effective database access
  • The /tmp directory for writing payloads and staging further tooling
  • Any file or directory where permissions are set too broadly (world-readable configs, group-shared directories)

On a traditional shared hosting server without per-user isolation, a single nginx RCE translates to read/write access across every customer's web root, every database credential in every config file, and the ability to drop and execute ransomware payloads in /tmp. That is the path from one CVE to encrypting 200 sites in under a minute.

On a Panelica server, the blast radius is structurally limited:

  • K3 (SSH chroot) and K5 (UID/GID isolation) mean each customer's files are owned by a dedicated system user. The nginx worker process does not run as those users. Cross-tenant file access requires the worker to read files it does not own -- blocked by Unix permissions when isolation is correctly configured.
  • K4 (PHP-FPM open_basedir) means PHP code executing in the web context cannot read outside its home directory boundary, even if the nginx worker is compromised.
  • K1 (Cgroups v2) constrains any payload that tries to spawn mass processes or consume memory for further exploitation staging.
  • K6 (AppArmor) -- see the next section -- is the layer specifically designed to contain what a compromised nginx worker can do at the OS call level.

The LPE chain risk: An attacker who achieves RCE as www-data on a Panelica server then faces the separate question of whether they can escalate to root. CVE-2026-46300 (Fragnesia) is a kernel LPE that chains directly. www-data + Fragnesia + a TCP socket = root. That is why both CVEs must be patched, not just nginx. The isolation layers slow and contain, but a kernel exploit running from any local context can cross them. Patch the kernel.


Panelica's 5-Layer Isolation and Why It Matters Here

Layer 1: Cgroups v2

Every user account on a Panelica server runs inside a dedicated cgroup slice at /sys/fs/cgroup/panelica.slice/panelica-user.slice/panelica-user-{username}.slice/. The slice enforces per-user limits on CPU time, memory, I/O bandwidth, and process count. While cgroups alone do not block a kernel exploit, they constrain the resource footprint available for exploit chains that require spawning large numbers of processes or consuming significant memory during the privilege escalation sequence. This raises the bar for reliable exploitation.

Layer 2: Linux Namespaces

Panelica creates per-user PID and mount namespace pairs, implementing a CageFS-style isolated rootfs per user. An attacker who achieves root inside their namespace context faces an additional barrier to escaping into the host namespace. Kernel-level exploits can theoretically cross namespace boundaries, but the combination of namespace isolation and the layers below narrows the effective attack surface.

Layer 3: SSH Chroot Jails

This is the strongest natural mitigation against Fragnesia in the Panelica architecture. Panelica operates two SSH modes:

  • sshjailed (default for most customers): SFTP-only, no shell. A user in this mode can transfer files but cannot execute binaries on the server. Fragnesia requires running an exploit binary locally. Users in sshjailed mode physically cannot run one.
  • sshfull (developer customers, opted-in): bash access inside a chroot. These users can upload and execute binaries. They represent the real Fragnesia risk segment on a Panelica server.

The default Panelica deployment assigns sshjailed mode to new users. The population of users who have explicitly opted into full shell access is small and typically self-selected as operators who understand the implications.

Layer 4: PHP-FPM Per-User Pools

Each user's PHP-FPM pool runs with open_basedir restricted to their home directory. More importantly for Fragnesia, disable_functions blocks every function capable of executing external binaries: exec, shell_exec, system, proc_open, passthru, popen, and pcntl_exec. A WordPress site, a Laravel application, or any PHP CMS running on Panelica cannot fork an exploit process from within its PHP context. Web-reachable code cannot trigger Fragnesia.

Layer 5: Unix Permissions and UID/GID Isolation

Each customer account gets a dedicated UID and GID. Home directories are mode 700. File operations that require elevated access use the write-to-temp-then-chown pattern. One customer's files are not accessible to another customer's process context. This limits the value of the 1-byte page-cache write primitive that Fragnesia provides, since the attacker needs their chosen target file to be accessible from their own UID context.

Layer 6: AppArmor MAC Profiles

Panelica ships a production-grade AppArmor management layer built across four components: apparmor_service.go (profile management and enforcement), apparmor_log_parser.go (continuous deny-event ingestion), apparmor_log_scheduler.go (scheduled log processing, wired into the main server scheduler at startup), and apparmor_suggestion_engine.go (AI-driven profile refinement based on observed deny events). Profile templates are seeded from 000161_seed_apparmor_templates at install time.

When a properly enforced AppArmor profile is active on the nginx worker process, a successful CVE-2026-42945 RCE runs into the following MAC restrictions:

  • Execution of arbitrary binaries downloaded into /tmp is blocked at the kernel call level
  • Writes outside the designated web root are denied before they reach the filesystem
  • Network socket creation from the worker process is restricted to expected ports and families
  • Capabilities including ptrace, mount, and privilege escalation primitives are blocked

This is precisely the layer that converts a theoretical "RCE-to-ransomware" chain into a contained, logged, audited event. The suggestion engine continuously tightens these constraints based on real observed workload behavior, so profiles are not static -- they adapt to what each nginx instance actually does in production.

One honest caveat: AppArmor protection applies only when profiles are in enforced mode. If a profile has been switched to complain mode, or if the nginx worker has no profile attached, this layer provides no containment. Operators should verify AppArmor enforcement status via the Panelica Security section and keep profiles in enforced mode for all public-facing services.

The Remaining Risk

Users in sshfull mode with a local bash shell represent a genuine Fragnesia risk, even on a Panelica server. The isolation layers reduce what a successful attacker can do once they achieve root, but they do not prevent the kernel exploit itself from succeeding in that shell context. For this segment, the kernel update is mandatory. There is no architectural substitute for patching the kernel.


CVE-2026-46300 Fragnesia: ESP-in-TCP Kernel Local Privilege Escalation

Context: The Dirty Frag Family

If you followed our earlier coverage of CVE-2026-43284 (Dirty Frag), Fragnesia is the third sibling. The first two members of this family were CVE-2026-43284 and CVE-2026-43500. All three exploit overlapping code paths in how the Linux kernel handles fragmented or reprocessed network data in contexts where security-sensitive state is assumed to be clean. Fragnesia emerged specifically as a side effect of an incomplete mitigation in the Dirty Frag patch series: the fix narrowed one attack surface but left an adjacent path open.

The Mechanism

Fragnesia targets the espintcp ULP (Upper Layer Protocol) mode available on TCP sockets in kernels with CONFIG_INET_ESPINTCP compiled in. The attack proceeds in three phases.

Phase 1 -- Populate receive queue via splice. An attacker opens a TCP socket and uses splice() to transfer data from a file descriptor into the socket's receive queue. The data remains as page-cache references rather than kernel copies. The pages are still logically owned by their source file.

Phase 2 -- Switch to espintcp mode. The attacker calls setsockopt(SO_ULP, "espintcp") on the socket. The kernel switches the socket's data path to ESP processing. It does not flush or invalidate the existing receive queue.

Phase 3 -- Trigger in-place decryption. The kernel now processes the queued pages as if they were incoming ESP ciphertext. It performs the decryption operation in-place, modifying the page-cache pages. Because the attacker controls the IV nonce used in the ESP header (injected as part of the splice payload), each trigger produces a deterministic 1-byte arbitrary write into the page cache of any readable file on the system.

A 1-byte arbitrary write into page cache translates to local privilege escalation through any number of well-understood kernel exploitation primitives. The attack does not require any special capabilities or elevated starting privileges beyond a local shell.

Affected Modules and Kernel Versions

The vulnerability lives in the esp4 and esp6 modules (IPv4 and IPv6 IPsec ESP transform handlers) and in rxrpc (the AF_RXRPC socket family used by AFS clients). All three modules share the affected ULP state management code.

Patched kernel versions as of May 13, 2026:

  • AlmaLinux 8: kernel-4.18.0-553.124.2.el8_10
  • AlmaLinux 9: kernel-5.14.0-611.54.4.el9_7
  • AlmaLinux 10: kernel-6.12.0-124.56.2.el10_1
  • CloudLinux: same version numbers with the lve suffix
  • Other distributions: netdev mailing list patch published May 13; distribution packages pending as of advisory publication

Discovery credit: William Bowling and the V12 team.

Temporary Mitigation

If you cannot apply the kernel update immediately, unloading the affected modules removes the attack surface:

rmmod esp4 esp6 rxrpc

To persist across reboots, add a blacklist file:

# /etc/modprobe.d/fragnesia-mitigation.conf
blacklist esp4
blacklist esp6
blacklist rxrpc

The side effect: if you are routing traffic through kernel-mode IPsec tunnels, those tunnels will break. If you use WireGuard (which runs in userspace, not through the espintcp path) or OpenVPN, you are not affected by the mitigation. If you are running IPsec, evaluate a userspace fallback before unloading the modules.


Operator Action Plan

For CVE-2026-42945 (nginx) -- Patch Today

The PoC is public. Automated scanners are already indexing vulnerable nginx deployments. This is not a "patch within the week" situation -- patch today.

Panelica operators: nginx 1.31.0 is live in the stable channel. Apply from Update Center, then Apply. Two changelogs accompany the release: nginx-panel covers the panel UI service, and nginx covers the customer-facing web server. Both detail the CVE-2026-42945 fix, build provenance (Ubuntu 22.04, gcc 11.4.0, GLIBC max 2.34), and apply behavior (panel: approximately 2 seconds of UI interruption with automatic reconnect; customer: graceful reload with drained connections).

After applying, verify with: /opt/panelica/services/nginx-panel/sbin/nginx -v -- output should report 1.31.0.

Non-Panelica nginx deployments: Pull 1.31.0 from the nginx.org packages, or rebuild from source. If you are running NGINX Plus R32-R36, apply the F5 advisory patch directly. There is no safe version below 1.31.0.

For CVE-2026-46300 (kernel) -- Watch Your Distro Channel

AlmaLinux and CloudLinux: Patched kernel packages are in the testing repository as of May 13. Apply with:

dnf update kernel

Then schedule a reboot. For production systems where a reboot requires a maintenance window, apply the module blacklist mitigation above as a bridge measure.

Ubuntu and Debian: Watch the distribution security mailing lists. The netdev patch was published May 13. Ubuntu and Debian typically follow within 24-72 hours for critical kernel CVEs. Apply the module unload command in the interim if you have any users in sshfull mode.

KernelCare and live-patching services: KernelCare livepatch is the no-reboot option -- check the portal for Fragnesia patch availability. Live patching avoids the reboot window entirely and is the lowest-disruption path for environments with strict uptime requirements. Patched AlmaLinux and CloudLinux kernels are rolling out; other distributions to follow.


The Bigger Picture

Two critical CVEs in a single week is not unusual. The Linux ecosystem is large, the codebase is decades deep, and the security research community -- now augmented by AI-driven analysis tooling -- is active and getting faster at finding what human code review missed for 18 years.

For hosting operators, the question is not just how fast your panel vendor patches. It is how much damage a successful exploit causes on servers running that panel. On a Panelica server, the answer is: considerably less than on a bare-OS deployment or a panel without per-user isolation. The 5-layer isolation architecture was not designed specifically to stop these two CVEs. It was designed to contain any privilege escalation path. Fragnesia and CVE-2026-42945 are just the latest demonstration of why that architecture matters.

Patch nginx today. Watch for the kernel update from your distribution. Keep AppArmor profiles in enforced mode. If you have questions about your specific deployment's exposure or want to work through the patching sequence for your infrastructure, the Panelica community forum is the right place: forum.panelica.com.

Share:
Kernel-integrated panel.