Context
Remediation for SECBUG-4150. When encoding PHP values to BSON, several sites in src/phongo_bson_encode.c narrow a size_t length to uint32_t or int without a bound check. A ~4 GiB PHP string reaches the encoder unvalidated, wraps the allocation size to zero, and memcpy writes attacker-controlled bytes past the heap buffer.
Affected sites
- src/phongo_bson_encode.c:646-657, phongo_zval_to_bson_value IS_STRING branch. Z_STRLEN_P (size_t) is assigned to v_utf8.len (uint32_t) then used in bson_malloc(len + 1) and memcpy. The only pre-sink check is bson_utf8_validate, which validates encoding, not length.
- src/phongo_bson_encode.c:159, phongo_bson_append_object Binary branch. intern->data_len (size_t) cast to (uint32_t) with no cap.
- src/phongo_bson_encode.c:217, phongo_bson_append_object Symbol branch. intern->symbol_len passed to bson_append_symbol (int) with no cap.
- src/phongo_bson_encode.c:280, phongo_bson_append IS_STRING branch. Z_STRLEN_P passed to bson_append_utf8 (int) without check; the libbson return value is ignored, so oversized fields are silently dropped.
Entry points with no length gate: ClientEncryption::encrypt value (src/MongoDB/ClientEncryption.c:1014), Query / BulkWrite / BulkWriteCommand comment and hint options (src/MongoDB/Query.c:95, src/MongoDB/BulkWrite.c:367, src/MongoDB/BulkWriteCommand.c:149,197), and every document field via phongo_zval_to_bson.
Fix
- Reject string and binary values whose length exceeds INT32_MAX (the BSON on-wire limit) with a PHONGO_ERROR_UNEXPECTED_VALUE exception, before any narrowing cast.
- Enforce the same cap in Binary and Symbol constructors so the invariant holds at object creation.
- Check the return value of bson_append_utf8 / bson_append_symbol / bson_append_binary and raise an exception on failure instead of silently dropping the field.
- Add PHPT coverage for oversized string and Binary inputs where feasible (guarded on 64-bit and available memory).
Links
Fixes SECBUG-4150.