fix(security): parameterize SQL, redact sensitive logs, harden ReDoS regexes#2239
Merged
Conversation
…regexes Resolves five high-severity CodeQL alerts: - py/sql-injection (alert 351): MemoryStore.get_all_knowledge now maps sort_by through a literal column allowlist and raises ValueError on unknown values instead of silently falling back — no caller-supplied string ever reaches the SQL. - py/clear-text-logging-sensitive-data (alert 350): the EMR agent's success line no longer prints the patient's name; identity fields remain visible in the on-screen details panel shown right after. - py/polynomial-redos (alerts 214/215/216): schedule/interval parsing now bounds input length to 256 chars before any regex work, bounds the digit quantifiers, and removes the ambiguous whitespace overlap (`\s*(?:am|pm)?` followed by `\s+`) in the from/to window regex.
Contributor
|
Verdict: Approve This PR closes five high-severity CodeQL alerts with tightly-scoped, correct fixes: it parameterizes the memory-store sort column against a literal allowlist, drops the patient name from the EMR success log (still shown on-screen right after), and length-caps + de-ambiguates three schedule-parsing regexes so hostile input can't drive pathological backtracking. Each fix ships with a matching test, and the behavior changes are safe — nothing downstream relied on the old silent fallbacks. Nice, focused security work. 🔍 Technical detailsIssues FoundNone blocking. Verification notes
Strengths
|
itomek
approved these changes
Jul 18, 2026
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.
Closes five open high-severity Python CodeQL alerts. Before: a memory-browser sort parameter was interpolated into SQL after only a silent-fallback check, the EMR agent wrote patient names into its plain-text success log, and three schedule-parsing regexes could be driven into pathological backtracking by hostile input from the schedules API. After: invalid sort columns fail loudly and never touch the SQL, the success log carries only the patient ID (identity fields still display in the details panel right after), and schedule parsing is length-bounded with linear-time patterns.
Alerts addressed (all fixed, none dismissed):
py/sql-injectionget_all_knowledgemapssort_bythrough a literal column allowlist; unknown values raiseValueErrorinstead of silently falling backpy/clear-text-logging-sensitive-dataprint_success); on-screen details panel unchangedpy/polynomial-redos\d{1,9}) + 256-char input cap inparse_intervalpy/polynomial-redospy/polynomial-redosXh/XmpatternTest plan
pytest tests/unit/test_scheduler.py tests/unit/test_memory_store.py— 374 passed (includes new tests: SQLisort_byraises, oversized/hostile schedule inputs rejected, all natural-language schedule formats still parse)pytest tests/unit/test_memory_router.py tests/unit/test_scheduler_api.py tests/unit/test_daemon_scheduler.py tests/unit/test_schedule_daemon.py— one failure reproduces identically on pristine origin/main (pre-existing, unrelated)python util/lint.py --all— exit 0