Jan 27, 2026·6 min read·30 visits
The `gmrtd` library, used to read ePassports, blindly trusts the length declared by the NFC chip. By presenting a chip that claims to hold 4GB of data, an attacker can force the reader into an infinite read loop, causing CPU exhaustion and an eventual Out-of-Memory (OOM) crash.
A Denial of Service (DoS) vulnerability in the gmrtd Go library allows a malicious NFC chip to crash reading applications by advertising a fake, massive file size (4GB+), leading to memory exhaustion.
We usually think of NFC security in one direction: a malicious reader skimming your credit card or passport in a crowded subway. We worry about shielding sleeves and cryptograms. But rarely do we consider the inverse scenario: what if the passport itself is the weapon?
Enter gmrtd, a Go library designed to handle the heavy lifting of parsing Machine Readable Travel Documents (MRTDs) via the ISO7816 protocol. It implements the complex dance of APDU commands required to authenticate and read data groups (DGs) from the chip—like your face photo or biometric fingerprints.
In a perfect world, hardware adheres to spec. In the real world, hardware lies. CVE-2026-24738 is a classic case of "implicit trust." The library assumes that if an NFC chip says, "I have a file here, and it is 4 gigabytes long," the chip is telling the truth. This assumption turns every border control kiosk or ID-verification mobile app using this library into a sitting duck for a simple resource exhaustion attack.
The vulnerability lies in how gmrtd handles BER-TLV (Basic Encoding Rules - Tag-Length-Value) encoded data. When you read a file from an ePassport, the first thing you get is a header. This header tells you what the data is (Tag) and how big it is (Length).
In the smart card world, lengths can be encoded in "short form" (one byte) or "long form." Long form allows you to specify massive sizes by using a prefix like 0x84, followed by four bytes representing the size. This theoretically allows a file size up to 4GB (0xFFFFFFFF).
The flaw is embarrassingly simple: gmrtd parsed this length and immediately committed to reading that many bytes. It didn't ask, "Does a 4GB photo make sense on a low-power smart card?" It didn't ask, "Do I even have enough RAM to hold this?" It just shrugged and entered a loop.
This is a logic bug class known as Uncontrolled Resource Consumption (CWE-400). By failing to validate the upper bound of the length field against a sanity limit (like the max size of an ISO7816 file or available memory), the code voluntarily enters a death spiral.
Let's look at the crime scene in iso7816/nfc_session.go. The ReadFile function is responsible for fetching the Data Group. Here is the logic before the fix:
func (nfc *NfcSession) ReadFile(fileId uint16) (fileData []byte, err error) {
// [1] Read the header from the chip
fileHeader, err := nfc.ReadBinary(0, 4)
// [2] Parse the Tag and Length.
// tmpTlvLength comes directly from the malicious chip.
tmpTag, tmpTlvLength, tmpBuf, err := tlv.ParseTagAndLength(fileHeader)
// [3] Set the target. No validation occurs here.
totalBytes = int(tmpTlvLength)
totalBytes += 4 - tmpBuf.Len()
// [4] The Loop of Doom
if fileBuf.Len() < totalBytes {
for {
// Calculate next chunk size
bytesToRead := min(maxReadAmount, totalBytes-fileBuf.Len())
// Read the chunk
tmpData, err := nfc.ReadBinaryFromOffset(fileBuf.Len(), bytesToRead)
// Append forever until OOM or totalBytes is reached
fileBuf.Write(tmpData)
}
}
}The code at [3] is the fatal error. It takes tmpTlvLength (which could be 4,294,967,295) and sets it as the goalpost. The for loop at [4] will then execute millions of times, issuing READ BINARY commands and appending the results to a byte slice until the Go runtime panics with an Out of Memory error or the CPU melts.
To exploit this, you don't need a supercomputer. You need a $150 Flipper Zero or a rooted Android phone running a card emulation app. The goal is to emulate an ePassport that looks normal during the initial handshake but becomes a monster when the reader asks for data.
Here is the attack chain:
DG2 (the facial image). This is standard procedure for almost all ID verification flows.READ BINARY command with a valid Tag (0x61) but a weaponized Length: 0x84 0xFF 0xFF 0xFF 0xFF (4GB).0x90 0x00) for every request.The victim application hangs immediately. If the application is single-threaded or the reading happens on the main UI thread, the interface freezes. Eventually, the operating system kills the process for consuming too much memory.
The remediation, applied in v0.17.2, is a lesson in defensive programming. The maintainers implemented hard limits on what the library is willing to accept from the external world. They realized that a passport photo is never going to be 4GB. In fact, it's rarely going to be larger than 30-40KB.
The patch introduces two key constraints in iso7816/nfc_session.go:
READ_FILE_MAX_TLV_LENGTH set to 65,535 bytes (64KB). If the chip declares a size larger than this, the library immediately aborts with an error.READ_FILE_MAX_CHUNKS set to 1000. This prevents a "slow loris" style attack where the chip returns valid total lengths but sends data 1 byte at a time to waste CPU cycles.Here is the diff for the fix:
// The Fix: Sanity Checks
if tmpTlvLength > nfc.readFileMaxTlvLength {
return nil, fmt.Errorf("[ReadFile] TLV length exceeds permitted maximum")
}
// Inside the loop
if chunkCnt >= nfc.readFileMaxChunks {
return nil, fmt.Errorf("[ReadFile] Max chunks reached")
}This turns an OOM crash into a graceful error message: "[ReadFile] TLV length exceeds permitted maximum". The application survives, logs the error, and the attacker is left standing there looking silly.
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
gmrtd gmrtd | < 0.17.2 | 0.17.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 (Uncontrolled Resource Consumption) |
| Attack Vector | Physical (NFC) |
| CVSS | 4.6 (Medium) |
| Impact | Denial of Service (DoS) |
| Patch | v0.17.2 |
| Exploit Status | PoC Available |
The software does not properly restrict the size or amount of resources that are requested or consumed, which can be used to consume all available resources.
Code16 Sharp versions from 9.0.0 up to (but not including) 9.22.3 are vulnerable to a missing authorization flaw in the Quick Creation Command feature. The ApiEntityListQuickCreationCommandController fails to validate entity-level 'create' policies before returning administrative form designs or processing database modifications. Authenticated users with restricted access can bypass policy boundaries to access creation configurations and insert records.
CVE-2026-49471 is a high-severity security vulnerability in Serena, an AI-assisted coding Model Context Protocol (MCP) toolkit. In versions prior to v1.5.2, Serena's built-in web dashboard exposes an unauthenticated Flask API on a predictable port. Lacking host validation and CSRF protections, this endpoint is vulnerable to DNS Rebinding. An attacker can lure a user to a malicious webpage, bypass the Same-Origin Policy (SOP), rewrite the AI agent's persistent memory, and execute arbitrary commands on the host operating system via the autonomous agent's shell execution engine.
The trapster honeypot package is vulnerable to a remote denial of service (DoS) vulnerability due to uncontrolled recursion during the parsing of malformed DNS compression pointers in the decode_labels function.
A critical Use-After-Free (UAF) memory corruption vulnerability exists in the oneringbuf Rust crate prior to version 0.8.0. The vulnerability allows safe Rust code to instantiate and clone reference wrappers that point to heap-allocated ring buffers. Dropping one wrapper prematurely reclaims the backing memory, leading to dangling pointer references and subsequent Use-After-Free or Double Free states.
Januscape (CVE-2026-53359) is a critical Use-After-Free vulnerability in the x86 Shadow MMU component of the Linux Kernel's KVM subsystem. A logic error in shadow page tracking permits unauthorized page reuse without validating architectural execution roles, leading to dangling pointers in reverse mapping (rmap) tracking entries during guest memory teardown.
CVE-2026-48282 is a critical unauthenticated path traversal and arbitrary file write vulnerability in the Remote Development Services (RDS) component of Adobe ColdFusion. The vulnerability allows a remote, unauthenticated attacker to bypass directory boundaries and write arbitrary files, including CFML-based web shells, onto the host server. This flaw is actively exploited in the wild and enables full unauthenticated remote code execution under the privileges of the ColdFusion service account.