mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
## Summary
`BigDecimal(String)` has O(N²) time complexity for N-digit strings on JDK versions before 18 ([JDK-8291514](https://bugs.openjdk.org/browse/JDK-8291514)). Five JSON parser methods — `parseInt32`, `parseInt64`, `parseUint32`, `parseUint64`, and `parseDouble` — pass user-controlled strings directly to `new BigDecimal()` without length validation.
A single JSON numeric value with 1,000,000 digits takes ~13 seconds to parse on JDK 17. This can be used to DoS any service that parses protobuf JSON messages with numeric fields from untrusted input.
### Benchmark (JDK 17, x86-64 Linux)
| Digits | BigDecimal construction time |
|--------|-----|
| 1,000 | 1.8 ms |
| 10,000 | 6.3 ms |
| 100,000 | 133 ms |
| 1,000,000 | **13.1 seconds** |
### Fix
Added a `parseBigDecimal()` helper that rejects strings longer than 1000 characters before constructing `BigDecimal`. This is generous — valid protobuf numeric values never exceed ~350 characters (Double.MAX_VALUE in non-scientific notation is ~309 digits).
### Affected JDK versions
- JDK 8, 11, 17 (all current LTS releases): **Vulnerable** — no built-in string length limit in BigDecimal
- JDK 18+: JDK itself limits BigDecimal string input to 1100 characters by default (JDK-8291514), but the protobuf-level check is still worthwhile as defense-in-depth
### Test
Added `testParserRejectOverlyLongNumericStrings` covering all 5 affected field types.
Closes #26908
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26908 from MindflareX:fix/java-bigdecimal-length-check
|
||
|---|---|---|
| .. | ||
| src | ||
| BUILD.bazel | ||
| pom_template.xml | ||