This document combines identified vulnerabilities in the go-toml/v2
project into a single list, removing duplicates and providing detailed descriptions for each.
-
Vulnerability Name: Integer Overflow in Date Parsing
-
Description: The
parseDecimalDigits
function in/code/unstable/parser.go
converts byte slices representing decimal digits into integer values. When processing date components (year, month, day) in functions likescanDateTime
(which is used to identify DateTime, LocalDateTime and LocalDate kinds), if an extremely large number is provided as input for these components, the repeated multiplication by 10 (v *= 10
) inparseDecimalDigits
could potentially lead to an integer overflow. This overflow might result in incorrect integer values being used for date components, bypassing the subsequent date validity checks (if any are implemented at a later stage, which is not evident in the provided code) or causing unexpected behavior in date/time handling within applications consuming the parsed TOML.Steps to trigger vulnerability:
- Prepare a TOML document containing a date with an extremely large year, month, or day value. For example, set year to a value close to the maximum value of
int
. - Send this TOML document to an application that uses
go-toml/v2
to parse the document and specifically processes date or date-time values. - Observe the application's behavior when handling the parsed date. If the integer overflow occurs and is not properly handled, the application might proceed with an invalid or unexpected date.
- Prepare a TOML document containing a date with an extremely large year, month, or day value. For example, set year to a value close to the maximum value of
-
Impact: An integer overflow in date parsing can lead to several potential impacts:
- Incorrect date validation: If validation is performed after parsing (which is not evident in the provided
parser.go
but might exist in decoding logic - not provided in PROJECT FILES), the validation logic might receive incorrect date components due to the overflow. If the wrapped-around value happens to fall into a valid range, it will bypass intended date validity checks. - Unexpected application behavior: Applications relying on correct date and time parsing might exhibit unexpected behavior or logic errors due to the use of overflowed and thus incorrect date values.
- Data corruption: In scenarios where parsed dates are used to index or manage data, an integer overflow could lead to data being associated with incorrect dates, effectively causing data corruption from a logical perspective.
- Incorrect date validation: If validation is performed after parsing (which is not evident in the provided
-
Vulnerability Rank: High
-
Currently implemented mitigations:
- None in
/code/unstable/parser.go
or related files provided in PROJECT FILES. The code does not implement any explicit checks for integer overflows during the digit parsing inparseDecimalDigits
or during the date component parsing inscanDateTime
. TheisValidDate
function mentioned in the original vulnerability description is not present in the provided PROJECT FILES, implying it might be in a different part of the codebase (possibly in thedecode.go
file from the original vulnerability description which is not in the PROJECT FILES). Even ifisValidDate
exists and performs date validation after parsing, it will not prevent or detect integer overflows that occur during parsing.
- None in
-
Missing mitigations:
- Integer overflow checks within
parseDecimalDigits
function in/code/unstable/parser.go
: Before or during the multiplication step (v *= 10
), checks should be implemented to detect potential integer overflows. Go does not panic on integer overflow, it wraps around. Explicitly checking for potential overflow before it occurs would be a more robust mitigation. For example, beforev *= 10
, check ifv > (maxInt / 10)
. - Input sanitization and range validation before parsing: Before even calling
parseDecimalDigits
, basic input sanitization could be applied to check for excessively long digit sequences that are likely to cause overflow. For example, limit the number of digits allowed for year, month, and day components.
- Integer overflow checks within
-
Preconditions:
- The attacker must be able to control the input TOML document that is parsed by an application using
go-toml/v2
. - The application must be processing date or date-time values from the parsed TOML document.
- The attacker must be able to control the input TOML document that is parsed by an application using
-
Source code analysis:
- File:
/code/unstable/parser.go
- Function:
parseDecimalDigits(b []byte) (int, error)
func parseDecimalDigits(b []byte) (int, error) { v := 0 for i, c := range b { if c < '0' || c > '9' { return 0, unstable.NewParserError(b[i:i+1], "expected digit (0-9)") } v *= 10 // Potential integer overflow here v += int(c - '0') } return v, nil }
- The
parseDecimalDigits
function iterates through the byte sliceb
. In each iteration, it multiplies the current value ofv
by 10 and adds the numeric value of the current digit. - If the input
b
contains a long sequence of digits, and the accumulated valuev
becomes very large, the multiplicationv *= 10
can lead to an integer overflow. - Go does not inherently prevent integer overflows, and the result will wrap around, leading to an incorrect integer value without an error being explicitly raised by
parseDecimalDigits
.
- Function:
scanDateTime(b []byte) (reference, []byte, error)
(and potentially other functions that parse dates, though onlyscanDateTime
is evident in PROJECT FILES)
- The
scanDateTime
function identifies potential date and time tokens. It's highly likely that this function, or functions called by it (not fully visible in provided files, but based on the original vulnerability description and common parsing patterns), will useparseDecimalDigits
to convert date components into integers. - The potentially overflowed integer values from
parseDecimalDigits
are then used to determine theKind
of the node (DateTime, LocalDateTime, LocalDate) and stored asData
.
Visualization:
[TOML Date String with large year] --> scanDateTime --> [Date component extraction - potentially using parseDecimalDigits] --> parseDecimalDigits --> [Integer Overflow Possible] --> [Incorrect Year Integer] --> Node{Kind: DateTime/LocalDateTime/LocalDate, Data: Incorrect Date String} --> [Downstream decoding/validation (if any) might be bypassed] --> Application uses incorrect date
- File:
-
Security test case:
- Objective: Verify if providing an extremely large year value in a TOML date string can bypass date validation (or lead to incorrect parsing if no validation exists at parsing stage), due to integer overflow, leading to incorrect date handling.
- Test setup:
- Create a simple Go application that uses
go-toml/v2
to unmarshal a TOML document into a struct containing atime.Time
field ortoml.LocalDate
/toml.LocalDateTime
/toml.DateTime
field. - The TOML document will contain a date string with a year value designed to be close to the maximum value for
int
in Go, to attempt triggering an integer overflow during parsing.
- Create a simple Go application that uses
- Test steps:
- Prepare a TOML file (
testcase.toml
) with the following content:
date_overflow_test = "9223372036854775807-01-01T00:00:00Z" # Max int64 year value - likely to cause overflow if parsed as int during intermediate steps. local_date_overflow_test = "9223372036854775807-01-01" # Max int64 year value for local date local_datetime_overflow_test = "9223372036854775807-01-01T00:00:00" # Max int64 year value for local date time
- Write a Go test function that reads
testcase.toml
, unmarshals it into a struct, and then examines the parsed date/time values. Test with different target types in the struct:time.Time
,toml.LocalDate
,toml.LocalDateTime
. - In the test, assert that either an error is returned during unmarshaling (indicating overflow detection, which is not currently implemented but would be a good mitigation) or, if no error is returned, that the parsed year in the date/time value is not the extremely large value provided in the TOML, and ideally, it should reflect the maximum possible valid year or some error handling behavior.
- Prepare a TOML file (
- Expected result:
- Ideally, the test should result in a
DecodeError
(or similar error fromgo-toml/v2
) indicating an invalid year or a range error during integer parsing, as the provided year is excessively large and would likely cause an overflow during intermediate parsing steps. - If no error is returned, then it indicates a vulnerability where integer overflow is not properly handled, and the parsed date is likely incorrect. In that case, the assertion should check if the parsed year is not equal to the intended large value, proving the overflow and incorrect parsing.
- Ideally, the test should result in a
- Code example for test case (pseudocode - update to test all date types):
package main_test import ( "testing" "time" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" "os" ) type Config struct { DateOverflowTest time.Time `toml:"date_overflow_test"` LocalDateOverflowTest toml.LocalDate `toml:"local_date_overflow_test"` LocalDateTimeOverflowTest toml.LocalDateTime `toml:"local_datetime_overflow_test"` } func TestIntegerOverflowDateParsing(t *testing.T) { tomlData, err := os.ReadFile("testcase.toml") require.NoError(t, err, "Failed to read testcase.toml") var cfg Config err = toml.Unmarshal(tomlData, &cfg) if err == nil { t.Logf("No error returned, potential vulnerability. Parsed DateTime year: %d, LocalDate year: %d, LocalDateTime year: %d", cfg.DateOverflowTest.Year(), cfg.LocalDateOverflowTest.Year, cfg.LocalDateTimeOverflowTest.LocalDate.Year) // Assert that the parsed year is NOT the large input year, indicating overflow for all date types require.NotEqual(t, 9223372036854775807, cfg.DateOverflowTest.Year(), "Integer overflow vulnerability exists in DateTime parsing: Incorrect date parsed.") require.NotEqual(t, 9223372036854775807, cfg.LocalDateOverflowTest.Year, "Integer overflow vulnerability exists in LocalDate parsing: Incorrect date parsed.") require.NotEqual(t, 9223372036854775807, cfg.LocalDateTimeOverflowTest.LocalDate.Year, "Integer overflow vulnerability exists in LocalDateTime parsing: Incorrect date parsed.") } else { t.Logf("Expected error returned (Mitigation might be in place or error during parsing): %v", err) require.Error(t, err, "Expected a DecodeError due to invalid or out-of-range date/year.") } } func main() { // Optional: Run test case directly if needed for quick validation // go test -run TestIntegerOverflowDateParsing main_test.go }
-
-
Vulnerability Name: Excessive Precision Processing in LocalTime Parsing
-
Description: An attacker can provide a maliciously crafted TOML document with an extremely long fractional part in a
LocalTime
value. When thego-toml
library parses this document, theparseLocalTime
function indecode.go
will attempt to process this excessively long fractional part, even though the precision is ultimately truncated to nanoseconds (9 digits). This processing of an unbounded fractional part can lead to increased CPU usage and processing time, potentially causing performance degradation if an attacker repeatedly sends such malicious TOML documents.Steps to trigger:
- Prepare a TOML document containing a
LocalTime
value with an extremely long fractional second part, for example:time_value = "12:34:56.123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
. - Send this TOML document to an application that uses
go-toml
v2 to parse TOML input, especially in scenarios where the input parsing is performance-sensitive or occurs frequently. - Observe the CPU usage and processing time on the server handling the parsing. Repeatedly sending such documents might amplify the impact.
- Prepare a TOML document containing a
-
Impact: An attacker can potentially degrade the performance of applications using
go-toml
by causing increased CPU consumption and processing time during TOML parsing. While not a complete denial of service, it can lead to a noticeable slowdown and resource exhaustion, especially under sustained attack or when processing large volumes of malicious TOML data. In scenarios where TOML parsing is a bottleneck, this vulnerability could exacerbate performance issues. -
Vulnerability Rank: High
-
Currently Implemented Mitigations: The
parseLocalTime
function in/code/decode.go
truncates the fractional part of seconds to a maximum of 9 digits (nanosecond precision). This prevents incorrect parsing or errors due to excessive precision. However, it does not prevent the function from processing arbitrarily long input strings before truncation, leading to the resource consumption issue. -
Missing Mitigations: Input validation is missing to limit the length of the fractional part of seconds in
LocalTime
values. A mitigation would be to add a check withinparseLocalTime
to limit the number of digits allowed in the fractional part, preventing excessive processing of very long strings. This could be implemented by setting a reasonable maximum length for the fractional part during parsing. -
Preconditions: The attacker must be able to provide TOML input to an application that uses
go-toml
v2 for parsing. This is a common scenario in applications that parse configuration files, accept user input in TOML format, or process external data in TOML format. -
Source Code Analysis:
- File:
/code/decode.go
- Function:
parseLocalTime(b []byte) (LocalTime, []byte, error)
- Vulnerable Code Section:
b = b[8:] // Move past "HH:MM:SS" if len(b) >= 1 && b[0] == '.' { frac := 0 precision := 0 digits := 0 for i, c := range b[1:] { // Loop iterates through fractional part if !isDigit(c) { if i == 0 { return t, nil, unstable.NewParserError(b[0:1], "need at least one digit after fraction point") } break } digits++ const maxFracPrecision = 9 if i >= maxFracPrecision { // Truncation logic is here, but the loop still runs. continue } // ... processing digits ... } // ... }
- Explanation:
- The
parseLocalTime
function is responsible for parsing the time part of a TOML datetime value. - After parsing the
HH:MM:SS
part, it checks for a fractional part starting with a dot (.
). - The
for
loop iterates through the bytes following the dot to parse the fractional seconds. - Vulnerability: The loop condition
for i, c := range b[1:]
iterates through the entire remaining byte sliceb[1:]
if all characters are digits, or until a non-digit character is encountered. There is no explicit check to limit the length of this fractional part before processing each digit. Even though the code truncates the precision tomaxFracPrecision = 9
, the processing still occurs for all digits in the input. - An attacker can provide an extremely long string of digits after the decimal point, causing the loop to iterate unnecessarily many times, consuming CPU resources.
- The
- File:
-
Security Test Case:
-
Create Test File: Create a TOML file named
malicious_time.toml
with the following content:time_value = "12:34:56.123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
-
Create Go Test Code: Write a Go test function that parses this TOML file and measures the parsing time.
package main import ( "testing" "time" "github.com/pelletier/go-toml/v2" "strings" "fmt" ) func TestExcessivePrecisionTimeParsing(t *testing.T) { tomlData := `time_value = "12:34:56.123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"` var config map[string]interface{} startTime := time.Now() err := toml.Unmarshal([]byte(tomlData), &config) parsingTime := time.Since(startTime) if err != nil { t.Fatalf("Unmarshal failed: %v", err) } fmt.Printf("Parsing time: %v\n", parsingTime) // You can add assertions here to check the parsed value if needed. }
-
Run Test and Observe:
- Run the Go test:
go test -run TestExcessivePrecisionTimeParsing
- Observe the "Parsing time" output.
- Run the test again with a shorter fractional second part (e.g., 9 digits or less) and compare the parsing times.
- You should observe a significantly longer parsing time for the malicious TOML document with the excessive fractional precision compared to a normal TOML document. You can also monitor CPU usage during the test to see if it increases with the malicious input.
- Run the Go test:
-
-
This test case demonstrates that processing a LocalTime
value with excessive fractional precision can increase parsing time, indicating a potential resource consumption vulnerability.