Refs #576: Reject control chars in treasury proposals#621
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR hardens treasury endpoints against control character injection by introducing a shared control character validator and applying it to request parsing functions. It adds comprehensive parametrized tests confirming both proposal and challenge creation endpoints reject control characters in key fields. ChangesTreasury Control Character Validation
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
yui-stingray
left a comment
There was a problem hiding this comment.
Reviewed current head c85285a035cea3cb0645efdb983407c43dd2ea67 and did not find a blocker.
I checked the focused treasury diff in app/treasury.py and tests/test_treasury_proposals.py. The shared control-character guard rejects C0, DEL, and C1 characters before trimming, and the integer payload path also rejects raw control characters before parsing. The added coverage exercises proposal action, issue_number, title, challenge challenge_type, and reason, with HTTP 400 responses and no persisted proposal/challenge rows on invalid input.
Validation performed:
git diff --check origin/main...origin/pr-621passedgit merge-tree --write-tree origin/main origin/pr-621succeededtests/test_treasury_proposals.pypassed: 28 testspy_compileon touched files passed- Ruff check and format check on touched files passed
- docs smoke passed
CodeRabbit reported no actionable comments, and GitHub quality checks are green.
eliasx45
left a comment
There was a problem hiding this comment.
Reviewed current head c85285a035cea3cb0645efdb983407c43dd2ea67.
Verdict: approve from technical review.
The treasury proposal/challenge hardening is focused and behaves correctly in the slice I checked. _clean_string() now rejects raw C0, DEL, and C1 control characters before trimming, so values like tab-prefixed actions or C1-padded titles cannot normalize into valid proposal payload fields. _payload_int() also rejects raw control characters before trimming/parsing integer strings, so issue-number style payloads do not silently normalize. The new tests cover proposal action, issue_number, title, and challenge challenge_type/reason, and assert no proposal/challenge rows are persisted on the malformed paths.
Validation on an updated origin/main:
git diff --check origin/main...HEAD
# clean
git merge-tree --write-tree origin/main HEAD
# 57dc3ebf1c952c34bf4cd709996f094f19ac58f6
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest -q tests/test_treasury_proposals.py --tb=short
# 28 passed
python -m py_compile app/treasury.py tests/test_treasury_proposals.py
# passed
python -m ruff check app/treasury.py tests/test_treasury_proposals.py
# passed
python -m ruff format --check app/treasury.py tests/test_treasury_proposals.py
# 2 files already formatted
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python scripts/docs_smoke.py
# docs smoke ok
Note: this is a code review only. I am not claiming this under #578 because the maintainer has already posted that the current review-bounty round is at capacity.
Summary
Evidence
Bounty #576 is open. Before this change, a request such as
action="\tcreate_bounty"to/api/v1/treasury/proposalswas accepted as cleancreate_bountyand created a pending proposal. The same raw-control-character-before-trim pattern also existed for treasury proposal payload integers/strings and challenge strings.This is distinct from the existing wallet/account/bounty/MCP/admin webhook/JSON integer/MRWK amount/wallet hex/activity control-character PRs because it covers treasury proposal and challenge canonicalization in
app/treasury.py.Validation
uv run --extra dev python -m pytest tests/test_treasury_proposals.py::test_treasury_proposal_creation_rejects_raw_control_characters tests/test_treasury_proposals.py::test_treasury_challenges_reject_raw_control_characters -q-> 5 passed, 1 warninguv run --extra dev python -m pytest tests/test_treasury_proposals.py -q-> 28 passed, 1 warninguv run --extra dev python -m pytest -q-> 487 passed, 1 warninguv run --extra dev ruff check .-> passeduv run --extra dev ruff format --check app/treasury.py tests/test_treasury_proposals.py-> passeduv run --extra dev mypy app/treasury.py app/treasury_routes.py-> successuv run --extra dev python scripts/docs_smoke.py-> docs smoke okgit diff --check-> cleangit merge-tree $(git merge-base HEAD origin/main) HEAD origin/main-> cleanNo private data, wallet material, tokens, signatures, admin token values, production mutation, price/liquidity/exchange/bridge/off-ramp claims, or private security details are included.
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests