NES for NGINX Release Notes
Comprehensive release notes and changelog for NES for NGINX, including security patches, bug fixes, and feature updates across all supported versions.
October 2026
1.31.2
Released Oct 20, 2026Release: v1.31.7-nes-1.31.2, NGINX 1.31.7, with njs 1.0.2 (QuickJS 2026.06.04) in nginx-module-njs.
Packages: signed RPMs for RHEL 8, 9 and 10 on x86_64 and aarch64, at https://registry.nes.herodevs.com/bin/nes/nginx/v1.31.7-nes-1.31.2/ (see Installation).
This release fixes the following CVEs:
NGINX
- CVE-2026-15176 (CVSS 3.1: 8.1 High; CVSS 4.0: 9.2 Critical), HTTP core (
alias,rewrite): Heap buffer overflow in a worker process. Afterrewritechanged the URI, and before a new location was chosen,$request_filenamestill mapped the new URI through the current location'salias; a rewritten URI shorter than the location prefix overflowed the path buffer, a longer one was mapped to the wrong file. Vulnerable 0.1.29-1.31.6; fixed upstream in 1.31.7 and 1.30.6. Advisories: nginx.org (medium), F5 K000162416. Fix: nginx 1.31.7, which nginx-nes is based on from v1.31.7-nes-1.31.2: nginx/nginxf8a23425bd68:ngx_http_map_uri_to_path()refuses to map whiler->uri_changedis set. Reachability: Reachable only withaliasand arewritewithoutbreakin the same location, and$request_filenameevaluated before the location changes: inreturn,set,iforadd_headerthere, or in that location's access log format. The packaged configuration usesroot, so not by default. Earlier NES builds are affected, though since the DAV alias backport they refuse a rewritten URI shorter than the prefix ("URI shorter than aliased URI part"), so only the wrong-file mapping remained there. - CVE-2026-93479 (CVSS 3.1: 8.1 High; CVSS 4.0: 9.2 Critical), Script engine (
ngx_http_script.c,ngx_stream_script.c): Heap buffer overflow in a worker process. When a string expression with variables evaluated longer than its length pass predicted,ngx_http_script_run()andngx_stream_script_run()let the copy spill into the space the caller reserved; the caller then wrote past the end of the buffer by up to that reserved size (for the document root, the length of the URI; for an access log file path, one NUL byte). Vulnerable 1.31.2-1.31.6 and 1.30.0-1.30.5; fixed upstream in 1.31.7 and 1.30.6. Advisories: nginx.org (medium), F5 K000162607. Fix: nginx 1.31.7, which nginx-nes is based on from v1.31.7-nes-1.31.2: nginx/nginx6aa4b3fdd4fd: the copy is bounded by the evaluated length, not by the length plus the reserved space. Reachability: Reachable when arootoraliaswith variables is used to map a request to a file (static files and$request_filename, throughngx_http_map_uri_to_path(), or$realpath_root), or anaccess_logfile path in http or stream has variables, and those variables change between the two passes: a regex capture used before amapthat matches by regex (which replaces the captures), or a non-cacheable variable. Not in the packaged configuration. - CVE-2026-95101 (CVSS 3.1: 5.3 Medium; CVSS 4.0: 6.9 Medium), HTTP/3 (
ngx_http_v3_module): Request body injection. The HTTP/3 request body parser kept the remaining length of an unknown (skipped) frame in the field the body filter uses for DATA payload; when such a frame was split across reads, its remainder was passed on as request body, unframed, bypassingclient_max_body_size(checked only on DATA frames) and injecting data into the proxied request. Vulnerable 1.25.0-1.31.6; fixed upstream in 1.31.7 and 1.30.6. Advisories: nginx.org (medium), F5 K000162613. Fix: nginx 1.31.7, which nginx-nes is based on from v1.31.7-nes-1.31.2: nginx/nginx1c173a2d8767: the skipped length is kept in its ownst->skipcounter. Reachability: Reachable only on an HTTP/3 listener (listen ... quic) that reads request bodies, such as proxying with request buffering (F5 namesproxy_request_buffering on, the default). The packages are built--with-http_v3_module, but the packaged configuration has no QUIC listener. - CVE-2026-97629 (CVSS 3.1: 6.5 Medium; CVSS 4.0: 8.3 High), SSL session tickets (
ngx_event_openssl.c): Session forgery. With automatic session ticket key rotation, each worker synced only two of its three ticket key slots from shared memory; the third kept uninitialized memory and was still matched by key name when decrypting, so a ticket naming it could be accepted with uninitialized key material, forging a session (F5: possibly bypassing client certificate verification). Vulnerable 1.23.2-1.31.6; fixed upstream in 1.31.7 and 1.30.6. Advisories: nginx.org (medium), F5 K000162606. Fix: nginx 1.31.7, which nginx-nes is based on from v1.31.7-nes-1.31.2: nginx/nginx1916f26e6ca4: all key slots are synced to the worker. Reachability: Reachable on SSL servers (http, stream, mail) withssl_session_cache shared:...and nossl_session_ticket_key(session tickets are on by default), the configuration that rotates ticket keys automatically. Whether a forged ticket is accepted depends on the uninitialized memory, which the attacker does not control. The packaged configuration has no SSL server. - CVE-2026-97205 (CVSS 3.1: 8.1 High; CVSS 4.0: 9.2 Critical), HTTP core, asynchronous file I/O (
ngx_http_copy_filter_module.c,ngx_http_file_cache.c,ngx_http_upstream.c): Use-after-free in a worker process. Each pending asynchronous file operation holds a reference in the request's 8-bitblockedcounter, which was not checked; 256 operations pending on one request, for example an SSI page with manyinclude virtualcommands, wrapped it to zero and the request could be freed while they still used its memory. Vulnerable 0.8.11-1.31.6; fixed upstream in 1.31.7 and 1.30.6. Advisories: nginx.org (medium), F5 K000162608. Fix: nginx 1.31.7, which nginx-nes is based on from v1.31.7-nes-1.31.2: nginx/nginx6adfc05ece48: at most 250 pending operations per request (NGX_HTTP_MAX_BLOCKED); beyond that, reads are synchronous or refused. Reachability: Reachable only withaio onoraio threads(the packages are built--with-file-aioand--with-threads;aiois off by default) and pages that start many file reads on one request, such as SSIinclude virtual. Not in the packaged configuration.
njs and QuickJS
- CVE-2026-101025 (CVSS 3.1: 5.3 Medium; CVSS 4.0: 6.9 Medium), njs: The built-in njs engine leaks a libxml2 parser context when
xml.parse()fails; the failure path never registered cleanup, so the context is never released. Repeated malformed XML input exhausts worker process memory. Fix: njs 1.0.2 pin bump (packaging/sources.json,MODULE_VERSIONS.md). Reachability: njs XML module used by the customer's js code. - CVE-2026-101019 (CVSS 3.1: 6.5 Medium; CVSS 4.0: 8.3 High), njs: The njs XML module exposes entity-backed XML attributes inconsistently with libxml2 canonicalization in both the built-in njs and QuickJS backends: the
$attr$Namegetter can returnundefinedfor an attribute that contains an internal entity reference, and$attrscan return a value derived from only the first attribute child. Affects signed XML validation (confirmed with nginx-saml on the built-in njs backend). Fix: njs 1.0.2 pin bump (packaging/sources.json,MODULE_VERSIONS.md). Reachability: njs XML module used by the customer's js code.
Upgrade notes
This release moves nginx from 1.31.6 to 1.31.7, the upstream release that
fixes this release's five nginx CVEs, and updates njs in nginx-module-njs
from 1.0.1 to 1.0.2. Check the following before upgrading.
nginx 1.31.7 (see the nginx 1.31.7 changes):
- A buffer size directive set to
0is now a configuration error:nginx -tfails, and nginx does not start or reload, with any ofclient_body_buffer_size,client_header_buffer_size,subrequest_output_buffer_size,proxy_buffer_size,fastcgi_buffer_size,grpc_buffer_size,memcached_buffer_size,scgi_buffer_size,uwsgi_buffer_size,tunnel_buffer_size,ssl_buffer_size,http3_stream_buffer_size,mp4_buffer_size,mp4_max_buffer_size,preread_buffer_sizeor the mail module'sproxy_bufferset to0. - When nginx verifies a backend's certificate (
proxy_ssl_verify,grpc_ssl_verify,uwsgi_ssl_verify, andproxy_ssl_verifyin stream) against a name that is an IP address, only iPAddress subjectAltName entries match it now; a certificate that has the address only in a dNSName entry or the commonName fails verification. - HTTP/2 now prioritizes responses with the RFC 9218 scheme (the
Priorityrequest header and PRIORITY_UPDATE frames) and ignores RFC 7540 priority signals. - An SSL connection closed without close_notify, a reset one included, is no longer treated as a clean shutdown: such connections now log "SSL_read() failed" errors.
njs 1.0.2 changes the njs XML API (the xml module). Check js code that uses
it:
- XML node mutation and canonicalization reject detached nodes, and a removed
child node has an undefined
$parent. - Text and attribute values must be primitive strings;
nullandundefinedkeep their deletion semantics. addChild()and$tagsreject source trees with namespaces.- In the QuickJS engine, assigning to
$tag$namethrows aTypeError; deleting it still works.
njs 1.0.2 also adds XMLNode.getAttributeNS() and XMLNode.getChildNS() for
namespace-aware lookups, and ngx.fetch() now rejects responses with
conflicting Content-Length fields, with both Transfer-Encoding and
Content-Length, or with a 1xx status code. See the
njs 1.0.2 changes.
From this release on, every RPM's file name carries the whole release:
<package>-v1.31.7-nes-1.31.2.el<RHEL version>.<architecture>.rpm, for
example nginx-v1.31.7-nes-1.31.2.el9.x86_64.rpm, where v1.31.6-nes-1.31.1
used the package's version and release (nginx-1.31.6-1.nes.el9.x86_64.rpm).
The signing key and checksum files keep their names. Update scripts that
download the RPMs by name. The packages themselves are named and versioned as
before (rpm -q nginx shows nginx-1.31.7-2.nes.el9.x86_64 on RHEL 9), so
dnf install upgrades v1.31.6-nes-1.31.1 as usual.