Redact pip/ensurepip stderr before bounding in gateway log warnings - #7292
Redact pip/ensurepip stderr before bounding in gateway log warnings#7292bolichen97 wants to merge 1 commit into
Conversation
The faiss-cpu install and ensurepip bootstrap failure sites in dashboard/handlers/memory.py logged decoded subprocess stderr via `stderr.decode()[:500]` with no redaction. A credential-bearing private index (`https://<user>:<token>@host/simple`) that answers 401 makes pip emit the raw URL into stderr (pip's warn_on_401 does not redact), which the faiss site then wrote unredacted into the gateway log. Route both sites through security.redact_and_truncate, which redacts the full decoded stream BEFORE applying the 500-char bound, matching the redact-before-bound invariant used by the sibling cron paths. This also closes the boundary-straddle gap where a secret spanning the 500-char cut could survive as an unredactable prefix. Adds regression tests covering the 401 credential-URL case, a boundary-straddle case, and the ensurepip site.
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — ✅ PASSDesign-level review of The diff is small and targeted: two log sites in Design-Verdict: PASS Reuses the existing redact-before-bound utility at the exact leak sites, root-cause fix with boundary-straddle tests; no design-level concerns. Suggestions
[DESIGN-REVIEWED] 5015796 |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — 🟡 CONCERNSPremise-level review of All checks are done. The fix uses the existing First-Principles-Verdict: CONCERNS The fix is real and uses the existing helper, but the same pip-401 credential leak survives unfixed at What this change shipsIntent: stop pip/ensurepip subprocess stderr from writing private-index credentials into the gateway log (issue #7279) — a FIX.
No undeclared items; the diff adds no new public surface, and it correctly reuses Watch
[FIRST-PRINCIPLES-REVIEWED] 5015796 |
|
Closing as superseded by #7283. Both PRs make the same fix — route pip/ensurepip stderr through #7283 is strictly better on two counts:
#7283 is also already fully green on every lane. Two further items would have to be fixed here Tracking the work on #7283. |
Summary
Fixes the unredacted subprocess-stderr logging in
src/kiro_crew/dashboard/handlers/memory.pyreported in issue #7279. Both pip/ensurepip failure sites loggedstderr.decode()[:500]with no redaction, unlike every neighbouring hardened subprocess path. On the faiss-cpu install site this can write a raw private-index-URL credential (e.g.https://<user>:<token>@host/simple) into the gateway log when the index answers 401, because pip'swarn_on_401logs the request URL raw.Changes
src/kiro_crew/dashboard/handlers/memory.pyredact_and_truncateto the existingfrom kiro_crew.security import ...import.stderr.decode()[:500]->redact_and_truncate(stderr.decode(), max_chars=500).security.redact_and_truncateand the sibling cron paths (cron: apply #4402's tail-slice + redact-before-truncate pattern to run_command_sandboxed and the stdout diagnostic #5547 / fix: redact cron stderr/stdout before truncating, report stderr tail #5574). This prevents a credential straddling the 500-char boundary from surviving as an unredacted fragment.test/test_enable_embeddings_faiss.py(new classTestSubprocessStderrRedactedBeforeBound)warn_on_401stderr line carryinghttps://svc:SECRET123@pypi.invalid/...is asserted redacted in the capturedlogger.warningrecord.SECRETfragment.Per the issue's scope note, site 897 has no index-URL credential vector (ensurepip installs from bundled wheels and consults no index); it is converted for consistency of shape on the same code path.
Testing
py_compileOK).kiro_crew.security.redact_and_truncate(importable without heavy deps): the 401-URL case strips the token, and the boundary-straddle case (secret spanning offset 495-504) yields output with no survivingSECRETfragment.Environment limitation
The full pytest suite for these handler tests imports
aiohttpand other runtime deps that are not installed in the sandbox, and the session network mode is 'Repository access only' (INTEGRATIONS_ONLY), which blocks installing them from PyPI. The redaction logic (the substance of the fix) was validated directly sincesecurity.redact_and_truncateis importable, but the aiohttp-based HTTP integration wrappers in the new tests could not be executed in-process. Please runpytest test/test_enable_embeddings_faiss.pyin an environment with dependencies installed to confirm the wired-up tests pass.Closes #7279