fix(api): reject trailing newlines in time_duration / parse_time_duration (#39730) - #39731
Open
Harsh23Kashyap wants to merge 1 commit into
Open
Conversation
…tion (langgenius#39730) Same bug class as the email validator fix in langgenius#39320, the password validator fix in langgenius#39548, and the alphanumeric validator fix in langgenius#39666 (merged 2026-07-28). Two more sites in api/libs/ used re.match with a '$' anchor; in Python '$' matches at end-of-string OR just before a trailing newline, so values like '7d\n', '30m\n', and '4h\n' slipped through. time_duration in api/libs/custom_inputs.py:6 is the field validator on WorkflowRunListQuery.time_range (api/controllers/console/app/ workflow_run.py:101). A time_range ending in '\n' is silently forwarded to the SQL WHERE clause — the same log-injection / header-injection surface that the email and alphanumeric fixes closed. parse_time_duration in api/libs/time_parser.py:7 is the same regex duplicated in a second file; used by the workflow scheduler and similar surfaces. Replace re.match with re.fullmatch in both, and add trailing-newline, trailing-CR, trailing-CRLF, leading-newline, and embedded-whitespace regression tests in both test files. The remaining re.match-with-trailing-newline sites in api/libs/ are either in path/URL validators that already have separate guards or in tool internals where the input is form-supplied; not a user-facing security surface. Filed the time_duration / parse_time pair here, and noted the rest for a follow-up sweep if maintainers want it.
Contributor
Pyrefly Type Coverage
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #39730.
Summary
Two time-input validators in
api/libs/usedre.matchwith a$anchor. In Python,$matches at end-of-string OR just before a trailing newline, so values like"7d\n","30m\n", and"4h\n"slipped through. Replacedre.matchwithre.fullmatchin both, matching the pattern established by the email fix in #39320, the password fix in #39548, and the alphanumeric fix in #39666 (merged 2026-07-28).Sites
api/libs/custom_inputs.py:6—time_duration. Field validator onWorkflowRunListQuery.time_range(api/controllers/console/app/workflow_run.py:101), the user-facing filter on the workflow-runs list endpoint.api/libs/time_parser.py:7—parse_time_duration. Same regex duplicated; used by workflow scheduling and similar surfaces.Why it matters
time_durationis the field validator on a real user-facing endpoint. A value with a trailing\nis silently forwarded to the SQLWHEREclause. The query still works (parameter binding is whitespace-tolerant), but downstream consumers that echo the value — log lines, error messages, response payloads — get the newline embedded. Same log-injection / header-injection surface that the email and alphanumeric fixes closed.Changes
api/libs/custom_inputs.py:6—re.match→re.fullmatchwith a 4-line comment matching the style of the email and alphanumeric fixes.api/libs/time_parser.py:7— same fix, same comment style.api/tests/unit_tests/libs/test_custom_inputs.py— 5 new tests inTestTimeDuration: trailing newline, trailing CR, trailing CRLF, leading newline, embedded whitespace.api/tests/unit_tests/libs/test_time_parser.py— 6 new tests inTestParseTimeDuration: trailing newline, trailing CR, trailing CRLF, leading newline, embedded whitespace.Verification
Broader sweep to make sure nothing else regressed:
Scope
Out of scope
A scan of
api/for otherre.matchpatterns with$anchors turned up a few more sites in path/URL validators that already have separate guards, and a couple in tool internals where the input is form-supplied. This PR is scoped to the two highest-impact, user-facing sites; happy to file a follow-up sweep if maintainers want it.