Skip to content

feat(malware-scan): Google Chat alert when the CI scan finds malware - #32

Merged
Satendra-SR merged 4 commits into
mainfrom
feat/malware-scan-chat-alerts
Sep 28, 2026
Merged

Satendra-SR merged 4 commits into
mainfrom
feat/malware-scan-chat-alerts

Conversation

@Satendra-SR

@Satendra-SR Satendra-SR commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

A failed malware scan only notifies the person who pushed, and in this attack that is the compromised account. This PR alerts the team's Google Chat space instead.

Changes

  • .github/workflows/malware-scan.yml
    • Adds an optional MALWARE_ALERT_WEBHOOK secret, so existing callers keep working unchanged.
    • The scan steps save their output and record their exit code.
    • A new Alert Google Chat step runs on failure:
      • Malware found (exit 1): posts the repo, branch, event, actor, short SHA, the HIGH count, the first 10 RULE path:line findings and the run link.
      • Scanner could not run (exit 2): posts a shorter "could not run" message.
      • Safety: code snippets are never sent (they are attacker-controlled). The payload is built with jq --arg and sent with plain curl, with no third-party action.
      • One message per alert: each alert posts as its own message, not in a thread.
      • Force-push flag: push alerts say "normal push" or "⚠️ FORCE-PUSH" (from github.event.forced), since this attack arrives by force-push.
      • Fail-safe: the step is skipped when the secret is absent, and uses continue-on-error so a Chat outage can't hide the real failure.
  • malware-scan/workflow.yml: the caller template passes only this one secret, not secrets: inherit.
  • malware-scan/README.md: a new "Alerts (Google Chat)" section covering setup, message contents and rotating the webhook. Setup uses a repository secret per project; a repo can point at its own space.

Testing

  • Both workflow files parse as YAML.
  • I ran the alert script locally with curl stubbed, against real scanner output. The malware message, the "could not run" message and the skip-without-secret path all behaved correctly.
  • End to end in a throwaway private repo: the alert arrived in Google Chat, the skip-without-secret path worked, and a normal push and a force-push were labelled correctly (FORCED: false / true), each as its own message.

Before relying on it (owner)

  1. Create the Chat webhook and add it as a repository Actions secret MALWARE_ALERT_WEBHOOK in each project that should alert. Organisation secrets are not an option: on GitHub Free, private repos can't read them.
  2. Update the repos already using the gate: add the secrets: block and bump the pinned SHA.

🤖 Generated with Claude Code

Satendra-SR and others added 4 commits September 28, 2026 13:08
…malware

The reusable workflow takes an optional MALWARE_ALERT_WEBHOOK secret. On a
failed scan it posts repo, branch, actor, the first 10 HIGH rule/path pairs
and the run link (no code snippets) with plain curl, threaded per repo. A
separate message is sent when the scanner cannot run. Skipped when the
secret is absent.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Org secrets aren't readable by private repos on GitHub Free.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@Satendra-SR

Copy link
Copy Markdown
Member Author

Added webhook alert for team to get into the incident quickly

@Satendra-SR
Satendra-SR merged commit 164436e into main Sep 28, 2026
1 check passed
@Satendra-SR
Satendra-SR deleted the feat/malware-scan-chat-alerts branch September 28, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant