fix(api): bound pagination integers and allocations - #173
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. |
6932143 to
37ce1eb
Compare
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
37ce1eb to
78931c4
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(api): reject overflowing pagination limits This is item 1/1 in the current shard. Shard 0/1. This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
|
🦞👀 Pull request received. I will update this pull request when review starts. |
Problem
CodeQL alerts 3-7 identify one pagination-boundary defect across the API and both stores:
strconv.Atoi, then reached PostgreSQLint32query parameters;Why
The HTTP boundary now parses pagination integers as signed 32-bit values before converting them to Go
int. Existing store normalization remains the canonical behavior owner: missing and zero values retain their documented defaults, negative values retain their existing rejection/default behavior, and oversized but representable values are still clamped to each endpoint's public maximum.PostgreSQL and SQLite member/search page builders now allocate directly from
len(rows)orlen(entries). This preserves backend parity and prevents request-controlled allocation expressions without changing returned pages.No public API, configuration, schema, SQL, generated code, or dependency surface changed.
User impact
Out-of-range pagination integers are rejected or fall back before database-width conversions. Valid requests, endpoint defaults, clamps, cursors, and page shapes are unchanged.
Evidence
Pre-fix regression:
Post-fix:
All passed with Go 1.26.6. The final command produced a statically linked 32-bit Intel 80386 test binary.
Boundary coverage includes missing/default, negative, zero, positive,
MaxInt32,MaxInt32+1, belowMinInt32, andMaxInt64. Existing store tests cover endpoint normalization and PostgreSQL/SQLite parity. No allocation-count assertion was added: the regression is the security boundary, while exact-head CodeQL independently verifies that request-sized allocation flows are gone.High-reasoning
gpt-5.6-solautoreview reported one proposedMaxInt32-1cap. Source tracing disproved it: search and member requests normalize to 100 and 200 before their sentinel-rowlimit + 1, while everyqueryIntconsumer clamps before SQL conversion or sentinel arithmetic.MaxInt32is therefore safe at ingress and never reaches backend addition.LOC split:
Crabbox clean-machine proof passed on exact head
78931c4:go test ./..., and Linux/386 cross-compile all passed;cbx_1174c9b3bcb8stopped automatically after exit 0.Exact-head GitHub proof on
78931c48949f8de468b7b476f1ed64fff972b6a2:1679826001onrefs/pull/173/headreported zero results;ClawSweeper requested explicit owner acceptance for changing strict search/member overflow from downstream clamping to an ingress error. @vincentkoc is an active
openclaw-secopsmaintainer and explicitly accepted the signed-32-bit ingress boundary for this campaign.Scope and credit
This updates the existing campaign-owned PR and branch created by @vincentkoc. No external contributor commit was copied. #169 is unrelated web cursor work and remains untouched.