This document combines two discovered vulnerabilities in the MongoDB Go Driver project into a single list, removing any potential duplicates and maintaining the detailed description for each.
-
Vulnerability Name: RawValue Type Confusion Vulnerability in BSON Decoding
-
Description:
- An attacker crafts a BSON document where a
RawValue
element has an invalidType
field (e.g.,0x00
- invalid type). - The attacker sends this crafted BSON document to an application that uses the MongoDB Go Driver and decodes BSON data into Go structs or interfaces that include
bson.RawValue
fields. - During decoding, the
rawValueEncodeValue
function inprimitive_codecs.go
checks if theRawValue.Type
is valid usingrawvalue.Type.IsValid()
. - However, if
RawValue.Type
is invalid (e.g.,0x00
), the condition!rawvalue.Type.IsValid()
becomes true. - The function incorrectly returns an error:
fmt.Errorf("the RawValue Type specifies an invalid BSON type: %#x", byte(rawvalue.Type))
. - Crucially, this error is returned during encoding (
rawValueEncodeValue
), not during decoding (rawValueDecodeValue
). TherawValueDecodeValue
function, responsible for decoding, does not validate theRawValue.Type
after reading it from the BSON stream. - When decoding a BSON document containing this invalid
RawValue
, therawValueDecodeValue
function inprimitive_codecs.go
will successfully decode the raw bytes without validating the type. - This allows an attacker to inject arbitrary bytes into a
RawValue
field, potentially leading to type confusion or unexpected behavior in application code that processes the decodedRawValue
. - The vulnerability lies in the inconsistent validation of
RawValue.Type
- it is validated during encoding but not during decoding, allowing invalid types to be deserialized.
- An attacker crafts a BSON document where a
-
Impact:
- High: Type confusion vulnerability. An attacker can inject arbitrary BSON data, including potentially malicious payloads, into
bson.RawValue
fields. This could lead to unexpected behavior, data corruption, or potentially escalate to more severe vulnerabilities depending on how the application processesbson.RawValue
data. - If the application directly uses the
RawValue.Value
without proper type checking after decoding, it might misinterpret the data, leading to logical errors or security bypasses.
- High: Type confusion vulnerability. An attacker can inject arbitrary BSON data, including potentially malicious payloads, into
-
Vulnerability Rank: high
-
Currently Implemented Mitigations:
- None in the
rawValueDecodeValue
function itself. - The
rawValueEncodeValue
function performs validation, but this is irrelevant for decoding vulnerabilities.
- None in the
-
Missing Mitigations:
- Input Validation in
rawValueDecodeValue
: TherawValueDecodeValue
function should validate theRawValue.Type
after reading it from the BSON stream, similar to howrawValueEncodeValue
does during encoding. If an invalid type is encountered,rawValueDecodeValue
should return an error, preventing deserialization of malformedRawValue
elements.
- Input Validation in
-
Preconditions:
- Application must be using
bson.RawValue
type in Go structs to represent raw BSON values. - Application must be decoding BSON data from untrusted sources (e.g., external input, network requests).
- Application must be using
-
Source Code Analysis:
// code/bson/primitive_codecs.go // rawValueEncodeValue is the ValueEncoderFunc for RawValue. // // If the RawValue's Type is "invalid" and the RawValue's Value is not empty or // nil, then this method will return an error. func rawValueEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { // ... (validation and encoding logic) if !rawvalue.Type.IsValid() { // VALIDATION DURING ENCODING return fmt.Errorf("the RawValue Type specifies an invalid BSON type: %#x", byte(rawvalue.Type)) } return copyValueFromBytes(vw, rawvalue.Type, rawvalue.Value) } // rawValueDecodeValue is the ValueDecoderFunc for RawValue. func rawValueDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error { // ... (decoding logic) t, value, err := copyValueToBytes(vr) // READS TYPE FROM BSON STREAM if err != nil { return err } val.Set(reflect.ValueOf(RawValue{Type: t, Value: value})) // NO VALIDATION OF 't' AFTER DECODING return nil }
Visualization:
graph LR A[Crafted BSON with invalid RawValue Type] --> B(Application decodes BSON); B --> C{rawValueDecodeValue (primitive_codecs.go)}; C --> D{Reads Type 't' and Value from BSON stream}; D --> E{Sets RawValue{Type: t, Value: value}}; E -- No validation of 't' --> F[RawValue with invalid Type in Go struct]; F --> G(Application processes RawValue.Value); G -- Type confusion/Unexpected behavior --> H[Potential Vulnerability Exploitation];
-
Security Test Case:
-
Setup: Create a simple Go application that:
- Defines a struct containing a
bson.RawValue
field. - Accepts BSON data as input (e.g., from standard input or HTTP request).
- Unmarshals the BSON data into the struct.
- Prints the
RawValue.Type
andRawValue.Value
to standard output.
- Defines a struct containing a
-
Craft Malicious BSON: Create a hex-encoded BSON document with a
RawValue
element that has an invalid type byte (0x00
) and arbitrary value bytes. For example, a minimal document structure could be:\x13\x00\x00\x00 // Document length: 19 bytes \xFF // Invalid Type (0xFF is just an example, 0x00 also works) \x00 // ElementName: "" (empty string) \x04\x00\x00\x00\x01\x02\x03\x00 // String value: "0x04 0x00 0x00 0x00 0x01 0x02 0x03 0x00" (just example bytes) \x00 // Document end
Hex representation of the above BSON:
13000000ff00040000000102030000
-
Execute Test:
- Run the Go application.
- Provide the crafted hex-encoded BSON document as input to the application (e.g., using
echo -ne '\x13\x00\x00\x00\xff\x00\x04\x00\x00\x00\x01\x02\x03\x00\x00' | go run your_app.go
).
-
Verification:
- Observe the output of the Go application.
- Vulnerability Confirmation: If the application successfully decodes the BSON document without errors and prints the
RawValue.Type
asinvalid
(or a similar unexpected type) and theRawValue.Value
contains the arbitrary bytes (\x01\x02\x03
in this example), then the vulnerability is confirmed. This indicates that the invalidRawValue.Type
was not rejected during decoding. - Expected Behavior (Mitigation): If the application throws an error during unmarshaling indicating an invalid BSON type or if the
RawValue
field is not populated due to a decoding error, then the vulnerability is likely mitigated.
-
-
-
Vulnerability Name: Truncated Multi-byte UTF-8 Characters in StringN
-
Description: The
StringN
function inbsoncore/value.go
truncates strings to a specified byte length (n
). When truncating multi-byte UTF-8 strings, the truncation might occur in the middle of a multi-byte character, leading to an invalid UTF-8 sequence. This can cause issues when the truncated string is used in contexts where valid UTF-8 is expected, such as display in user interfaces, logging systems, or other downstream systems that rely on valid UTF-8.Steps to trigger vulnerability:
- Create a BSON string value containing multi-byte UTF-8 characters (e.g., "你好世界").
- Call the
StringN
function on this value with a byte length that truncates a multi-byte character (e.g., length of 4 for "你好世界"). - Observe the output string, which will contain an invalid UTF-8 sequence.
-
Impact: The impact of this vulnerability is categorized as high because it can lead to data corruption or misrepresentation when handling UTF-8 strings. Specifically:
- Data corruption: Truncating a string in the middle of a multi-byte character can result in invalid UTF-8 data. If this corrupted data is persisted or transmitted, it can lead to data corruption issues in downstream systems that expect valid UTF-8.
- Misrepresentation of data: When displaying or logging the truncated string, the invalid UTF-8 sequence might be rendered incorrectly, leading to misrepresentation of the intended data. This could have security implications if the misrepresented data is used for security decisions or auditing.
-
Vulnerability Rank: high
-
Currently implemented mitigations: There are no mitigations implemented in the
StringN
function to handle multi-byte character truncation. The function directly truncates the byte slice without considering UTF-8 encoding. -
Missing mitigations: The
StringN
function should be updated to truncate strings correctly at UTF-8 character boundaries instead of byte boundaries. This can be achieved by iterating over the string's runes and truncating after a complete rune, ensuring that the resulting string is always valid UTF-8. -
Preconditions: The following preconditions are necessary to trigger this vulnerability:
- The application must use the
bsoncore
library to handle BSON data. - The application must use the
StringN
function to truncate BSON string values. - The BSON string values being truncated must contain multi-byte UTF-8 characters.
- The truncation length must be such that it cuts a multi-byte UTF-8 character in the middle.
- The application must use the
-
Source code analysis: The vulnerability exists in the
StringN
function in/code/x/bsonx/bsoncore/value.go
.func (v Value) StringN(n int) string { if n <= 0 { return "" } switch v.Type { case TypeString: str, ok := v.StringValueOK() if !ok { return "" } str = escapeString(str) if len(str) > n { truncatedStr := bsoncoreutil.Truncate(str, n) // Vulnerability is here, byte-based truncation return truncatedStr } return str ... }
The
bsoncoreutil.Truncate(str, n)
function performs byte-based truncation, which is problematic for UTF-8 strings.// Truncate truncates a given string for a certain width func Truncate(str string, width int) string { if width == 0 { return "" } if len(str) <= width { return str } // Truncate the byte slice of the string to the given width. newStr := str[:width] // Byte-based truncation ... }
The file
/code/internal/integration/clam_prose_test.go
includes tests for command logging and monitoring, and it uses a similar truncation functionlogger.Truncate
for logging messages. While this file contains tests to check for multi-byte character handling in logging, the underlyinglogger.Truncate
function, likebsoncoreutil.Truncate
, is also byte-based and could potentially lead to invalid UTF-8 sequences in logs if not carefully handled. Although the testclamMultiByteTruncLogs
attempts to mitigate this by ensuring the last bytes are part of a multi-byte character, this is not a general solution and might not cover all cases where logging truncation could occur. -
Security test case:
- Create a Go test file (e.g.,
stringn_vulnerability_test.go
) in the same directory as/code/x/bsonx/bsoncore/value.go
. - Add a test function
TestStringNTruncationVulnerability
to this file. - Inside the test function, construct a BSON Value of type string containing multi-byte UTF-8 characters, for example "你好世界".
- Call
StringN
with a truncation length that will split a multi-byte character, e.g., length 4. - Assert that the resulting string is not a valid UTF-8 string, indicating the vulnerability. You can use
utf8.ValidString
to check for UTF-8 validity.
package bsoncore import ( "testing" "unicode/utf8" ) func TestStringNTruncationVulnerability(t *testing.T) { testString := "你好世界" // Multi-byte UTF-8 string val := Value{Type: TypeString, Data: AppendString(nil, testString)} truncatedString := val.StringN(4) // Truncate in the middle of multi-byte character if utf8.ValidString(truncatedString) { t.Errorf("Expected invalid UTF-8 string, but got valid UTF-8: %q", truncatedString) } }
Run this test case to confirm the vulnerability.
- Create a Go test file (e.g.,
-