Failure scenario
- Enable the Slack notifier with
scrub_secrets=true.
- Call the formatted send path with a normal title/message but put credential-shaped text in
source or severity (the Web API accepts both fields from the request body).
- Inspect the JSON posted to Slack.
send_formatted() scrubs only title and message. build_formatted_payload() copies source and uppercases severity into attachment fields unchanged. send() then sees a custom payload and scrubs only its top-level text, not nested attachment fields. The credential-shaped metadata is therefore transmitted despite secret scrubbing being enabled.
The same nested-payload behavior affects any caller of send(..., payload=...): secrets in blocks or attachments are not scrubbed.
Sites
src/notifications/slack.py:57-61 copies source and severity into nested fields.
src/notifications/slack.py:151-155 scrubs only top-level text for custom payloads.
src/notifications/slack.py:185-192 leaves formatted metadata unscrubbed.
src/web/api/integrations.py:498-505 supplies request-controlled severity and source to this path.
Expected result
Scrub every user-controlled string in the complete outgoing Slack payload, including nested attachments/blocks and formatted metadata, before posting it.
Failure scenario
scrub_secrets=true.sourceorseverity(the Web API accepts both fields from the request body).send_formatted()scrubs onlytitleandmessage.build_formatted_payload()copiessourceand uppercasesseverityinto attachment fields unchanged.send()then sees a custom payload and scrubs only its top-leveltext, not nested attachment fields. The credential-shaped metadata is therefore transmitted despite secret scrubbing being enabled.The same nested-payload behavior affects any caller of
send(..., payload=...): secrets in blocks or attachments are not scrubbed.Sites
src/notifications/slack.py:57-61copiessourceandseverityinto nested fields.src/notifications/slack.py:151-155scrubs only top-leveltextfor custom payloads.src/notifications/slack.py:185-192leaves formatted metadata unscrubbed.src/web/api/integrations.py:498-505supplies request-controlled severity and source to this path.Expected result
Scrub every user-controlled string in the complete outgoing Slack payload, including nested attachments/blocks and formatted metadata, before posting it.