util: validate Duration/Timestamp in TimeUtil::FromString against spec limits#27443
util: validate Duration/Timestamp in TimeUtil::FromString against spec limits#27443jortles wants to merge 3 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
0e70dd4 to
e7f292a
Compare
14ba6cb to
b6c8f3f
Compare
|
Added two test cases and a fix: Tests (
Fix: Moved seconds range check before All 15 tests in |
46427d8 to
b53f717
Compare
…c limits TimeUtil::FromString accepted malformed inputs that produce protos failing IsDurationValid/IsTimestampValid. This includes: - Duration with mismatched signs (seconds<0, nanos>0) - Duration with >9 fractional digits (nanos > 999999999) - Duration with seconds > 315576000000 - Timestamp with year 0000, 10000+, 5-digit years, negative years The companion JSON parser (JsonStringToMessage) correctly rejects all these inputs, creating a cross-API divergence. Add IsDurationValid/IsTimestampValid checks after parsing in each FromString overload. Return false and clear output on failure. Found by: AFL++ property-check fuzzing Signed-off-by: Anthony Hurtado <[email protected]>
Adds tests for all 8 malformed input classes: - Duration: leading whitespace + negative, double minus, >9 fractional digits, seconds out of range - Timestamp: year 0000, year 10000 Also moves the seconds range check before CreateNormalizedTimestamp() to avoid hitting its DCHECK in debug builds before the IsTimestampValid check can run.
b53f717 to
0a44a86
Compare
|
@jortles looks like cmake test is failing, can you fix? |
|
There seems to be a CLA check error. Could we resolve this before continuing? Thanks! |
df20a69 to
20fca1a
Compare
On 32-bit platforms, absl::ToTimespec clamps to INT32_MAX/MIN when seconds overflow time_t. This silently converts out-of-range timestamps into in-range values, causing validation to pass for years like 0000 and 10000. Replace ToTimespec with ToUnixSeconds (returns int64_t) so the full 64-bit seconds value reaches the range checks.
20fca1a to
b57f445
Compare
Summary
TimeUtil::FromStringfor bothDurationandTimestampaccepts malformed inputs that produce protos failingIsDurationValid/IsTimestampValid.JsonStringToMessage) correctly rejects all the same inputs, creating a cross-API divergence." -3.54s")"--3.54s")"0.1234567890s")"315576000001s")"0000-12-31T23:59:59Z")"10000-01-01T00:00:00Z")"99999-01-01T00:00:00Z")"-0001-01-01T00:00:00Z")Fix: Add
IsDurationValid()check after parsing in the Duration overload, andIsTimestampValid()check in the Timestamp overload. Return false and clear output on failure. Both validation functions already exist inTimeUtiland are used byABSL_DCHECKelsewhere.Impact: Systems using Duration/Timestamp for security-relevant time bounds (gRPC deadlines, Envoy timeouts, retry intervals, IAM token TTLs). Class A is most dangerous:
seconds * 1e9 + nanosgives-2.46e9instead of intended-3.54e9— a 31% magnitude shift. 17 fuzzer crash inputs collected.Found by AFL++ property-check fuzzing (
pb_json_wkt_fuzzermode 1).Test plan
TimeUtil::FromString(" -3.54s", &d)returns false (class A)TimeUtil::FromString("--3.54s", &d)returns false (class B)TimeUtil::FromString("0.1234567890s", &d)returns false (class C)TimeUtil::FromString("315576000001s", &d)returns false (class D)TimeUtil::FromString("0000-12-31T23:59:59Z", &t)returns false (class E)TimeUtil::FromString("10000-01-01T00:00:00Z", &t)returns false (class F)