Skip to content

Missing Null-Terminator Content Check in VerifyTerminator() #9085

@Alearner12

Description

@Alearner12

Description

While auditing the FlexBuffers verifier, I discovered a bug in flexbuffers::Verifier::VerifyTerminator(). The function is intended to ensure that an FBT_STRING value has a valid null terminator at offset size. However, the current implementation only verifies that the byte at that offset lies inside the buffer; it does not check that the byte equals 0x00.

// include/flatbuffers/flexbuffers.h:
bool VerifyTerminator(const String& s) {
  return VerifyFromPointer(reinterpret_cast<const uint8_t*>(s.c_str()),
                           s.size() + 1);
}

As a result, VerifyBuffer() incorrectly accepts FlexBuffers whose strings are not actually null-terminated. A subsequent call to AsString().c_str() followed by strlen() or strcmp() reads past the verified region, resulting in a Heap Out-Of-Bounds Read (CWE-125).

This is a sibling bug to the recently fixed logic inversion in VerifyKey() (Issue #9072, commit a6979fe), sharing the exact same vulnerability primitive. The non-flex VerifyString() properly checks the terminator content (Check(buf_[end] == '\0')).

Impact

Any application parsing untrusted FlexBuffers and using standard C-style string APIs on the parsed strings is vulnerable to Heap OOB Reads, leading to information disclosure or Denial of Service (crashes).

Proposed Fix

I have submitted a Pull Request that aligns VerifyTerminator() with the non-flex verifier by adding the missing content check, alongside a regression test:

bool VerifyTerminator(const String& s) {
  const uint8_t* p = reinterpret_cast<const uint8_t*>(s.c_str());
  return VerifyFromPointer(p, s.size() + 1) && p[s.size()] == 0;
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions