Repository navigation
fix(people): reject executable ASGI scalar subtypes before authentication #321
Description
Finding
The governed People/Employment HTTP ingress accepted subclassable transport scalars through isinstance(...) and then executed methods on them before authentication.
Canonical People owner #55 predecessor d9803ae86fbc63bb41197c55d071dbba033361e8 used isinstance(path, str) before len(path) / route tokenization, and _parse_worker_request(...) used isinstance(raw_query, bytes) before len(...) / decode(...). Employment HTTP owner #155 reproduced the same mechanism in its own route/parser.
Python str and bytes are subclassable. A subtype can override __len__, strip, or decode; therefore these isinstance(...) gates admitted executable caller-defined behavior before authentication. ASGI path/query scalar authority must be exact built-in str/bytes, not an arbitrary subtype.
Canonical #55 RED → repair
- RED
32585ce837daf01f8fd7e92b71676825674d55bc:test_http_scalar_integrity.pyuses trappingstr/bytessubclasses and requires 404/400 with zero authentication/persistence calls. The predecessor accepts the objects and executes the first overridden method. - repair
e3c8a1efabdae3da2c33fc75cb27d925e2b60c9b: canonical People path/query ingress now requires exact built-in types before length/tokenization/decode while preserving response semantics.
Employment #155 independent RED → repair
- Parent adoption: feat(people): add purpose-bound Employment history read #149 ordinary-forward adopts current fix(people): harden governed People reads #55 in
5de7207c84cda5f5d8e2f358e379748d95acb9e4. - RED
a6862f7f37184265a4827cf40cfbec0faff8ed09: Employment route adds its own trapping path/query subtype regressions. - repair
e1618605d64262f7aea6a7e53692ce0903a946a1: Employment path/query ingress now requires exact built-in types. - ADR/traceability current through feat(people): expose employment history HTTP read #155 exact
49f5f2542ea0569b0e3b2de8371b7ab88f1b0feb. - feat(people): add PostgreSQL Employment-history read adapter #156 ordinary-forward adopts current feat(people): expose employment history HTTP read #155 and records lineage at exact
05e3aea18fd6e2e7a1148a514683b86c72e1373a.
Position-history #154 independently carries the same mechanism (d64f4b09... → d48927a9...). Sibling evidence is not substituted for any owner's acceptance.
Acceptance path
Keep this issue open until #55 reaches exact-head acceptance and protected integration. #149/#155/#156 remain Draft descendants and must later ordinary-forward onto protected truth and reacquire Foundation/Security/SAST/CodeQL/model review plus qualifying independent approval. No predecessor verdict transfers.
No force-push, destructive rebase, self/model approval, no-op retrigger, gate weakening, or mutable sibling source copy.
Activity