[Task]: FLIP-PT pentest remediation tracker — Final Report v2.0 (2026-05-06) - #975
Closed
atriaybagur wants to merge 1 commit into
Closed
[Task]: FLIP-PT pentest remediation tracker — Final Report v2.0 (2026-05-06)#975atriaybagur wants to merge 1 commit into
atriaybagur wants to merge 1 commit into
Conversation
…S3 keys, URLs, headers or bodies in logs (FLIP-PT-005) Adds a Logging policy section to the sys-admin docs and brings every service in line with it: - data-access-api: driver/parser error text (psycopg2 LINE context, SQLAlchemy [SQL: ...] suffix, sqlglot fragments) no longer reaches logs; errors log the exception class + SQLSTATE + a SHA-256 query fingerprint (utils/log_hygiene.py, normalisation matches the query cache key). The trust-side parse-reject detail becomes a fixed string (friendly parse feedback is the hub pre-check's job). OMOP engine gains hide_parameters=True. - imaging-api: the decoded cohort query is logged as a fingerprint, the DQR study-query response body (patient-level metadata) is no longer logged, and PACS-loop errors log the exception class only. - trust-api: the request debug log drops headers (service key), body (cohort SQL) and params (encoded_query); transport-error logs render host + path with the query string dropped. - flip-utils (fl-client/server): accession numbers are logged as fingerprints (Utils.hash_for_log), the row-level cohort dataframe and imaging response bodies are no longer logged, and cleanup logs no longer name accession-derived paths. - flip-api: cohort-path error logs are class-only (the bound INSERT parameters carry the raw SQL), the model-retrieval debug log drops the query text, s3_client extends the existing bucket= key_hash= style to every remaining verbatim-key message, and both engines set hide_parameters=True. Unit tests pin each scrubbed site (caplog / patched-logger assertions that the sensitive value stays out). Root CLAUDE/AGENTS carry the policy summary; the logging-stack component doc cross-references it. Signed-off-by: at24_bioeng625-pc <alexandre.triay_bagur@kcl.ac.uk>
95 tasks
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
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.
Addresses FLIP-PT-005 (remainder — the accession-ID log scrubbing landed in #839). Contributes to #429.
What this does
Defines the platform logging policy (
docs/source/sys-admin.rst#logging-policy) and brings every service in line with it. The rule set, applied at every log level: no cohort SQL (log a 12-hex SHA-256 fingerprint instead), no accession numbers or patient-level attributes (ordinals / counts / fingerprints), no secrets (headers, bodies, presigned URLs), no full URLs (host + path, query string dropped), no verbatim S3 keys (bucket + hashed key, or the model-id/file-name identifiers the key derives from).Per service
get_recordserror paths logged raw driver text, and psycopg2/SQLAlchemy interpolate the executing statement into it (LINE 1: …context,[SQL: …]suffix); sqlglot parse errors quote the offending fragment. All now log exception class + SQLSTATE + query fingerprint (utils/log_hygiene.py; normalisation matches the query-cache key, so cache and error lines for one query correlate — and the hub stores every cohort query, so ops can re-hash to find matching lines). The parse-reject 400 detail becomes a fixed string: sqlglot's message embeds the SQL, trust-api logs error bodies, and friendly parse feedback is the hub pre-check's job (a parse-invalid query normally never reaches a trust). TheUndefinedTable/UndefinedColumnoperator-echo diagnostics are preserved (identifier only, context dropped). OMOP engine gainshide_parameters=True(stopsperson_idlists rendering in wrapped driver errors).{e}logs become class-only (a pydanticValidationErrorrenders its input, a requests error the full URL).utils/http.pylogged request headers (the trust-internal service key), the JSON body (decrypted cohort SQL), and params (encoded_queryis base64-wrapped SQL) at DEBUG; now method + URL only. Transport-error logs render host + path (httpx merges params intorequest.url), and the 502 detail carries the exception class instead ofstr(e).get_dataframelogged the entire row-level cohort response body at INFO; now status code only. Accession numbers in download logs become fingerprints (Utils.hash_for_log), and cleanup no longer names accession-derived paths (in messages or in the raised exception).s3_clientextends FLIP-PT-080: disable SQLAlchemy engine echo on data-access-api #431'sbucket= key_hash= error_code=style to every remaining verbatim-key message, and both engines sethide_parameters=True.Deliberate scope boundaries
detail=str(e)sweep, centralised handler) stay with the in-flight Security: consolidate ten pentest-tracker fixes (#879, #888-#894, #912, #913) #930 — only bodies that were already being logged, or that carried SQL, changed here.str(e)sites Security: consolidate ten pentest-tracker fixes (#879, #888-#894, #912, #913) #930's sweep covers, so they're left for it rather than duplicated here.<model_id>/<file_name>, both user-visible metadata) remain loggable in that decomposed form — the policy doc records this decision explicitly.Verification
make local_test(ruff + mypy + 1616 unit tests) greenflip-utils changes are log-line-only (no control-flow change), but since the package runs inside both FL backends' images, a smoke on one backend before merge is cheap insurance if reviewers want it.