Skip to content

Harden recurring Microsoft Defender checks for released Windows binaries #58114

Description

@dsyme

Problem

Microsoft Defender currently flags the official v0.87.10/windows-amd64.exe release asset as PUAMiner:Win32/RedbyrepMiner, even though the asset matches its published SHA-256 checksum. A similar signature-specific false positive previously affected only v0.85.4 and was later corrected by Microsoft.

Because Defender signatures change after publication, a binary can pass the release-time gate and become blocked later. We need deterministic, recurring CI coverage that records enough evidence to distinguish a release-integrity problem, a Defender false positive, and a transient runner/service failure.

Current evidence (2026-09-03)

Scans ran on Windows with Defender product/engine 4.18.26080.3, signatures 1.459.14.0, and real-time protection enabled. Every downloaded executable matched the SHA-256 in its release's checksums.txt.

Version Kind Defender result
v0.86.2 stable Clean
v0.86.3 prerelease Clean
v0.87.0 prerelease Clean
v0.87.1 prerelease Clean
v0.87.2 prerelease Clean
v0.87.4 prerelease Clean
v0.87.5 prerelease Clean
v0.87.8 prerelease Clean
v0.87.9 prerelease Clean
v0.87.10 stable PUAMiner:Win32/RedbyrepMiner

v0.87.3, v0.87.6, and v0.87.7 were not published.

Affected asset details:

  • Asset: v0.87.10/windows-amd64.exe
  • SHA-256: 992f9a423ca69ceeb6f8772d8e2d3712c7d32ce4b59aa120ed2db6eed55fe894
  • Detection: PUAMiner:Win32/RedbyrepMiner
  • Threat ID: 344388
  • Category ID: 27
  • Severity ID: 5
  • MpCmdRun.exe exit code: 2

As a historical control, v0.85.4 now scans clean with signatures 1.459.14.0, showing that Defender's classification can change independently of the released bytes.

Current workflow state

Release workflow

.github/workflows/release.md already has a defender job on windows-latest:

  • The push_tag job builds dist/ and uploads release-binaries-<tag>.
  • The defender job downloads that artifact, updates Defender signatures with retries, logs Defender status/preferences, copies each windows-*.exe outside the workspace, verifies the source/copy hash, and runs MpCmdRun.exe -Scan -ScanType 3 -File <path> -DisableRemediation.
  • It rejects nonzero exits, skipped/excluded scans, threat output, and scans without both start and completion markers.
  • The release publication path depends on this gate, so binaries are scanned before the GitHub release is created.

This is a good release-time gate and should remain required.

Recurring post-release workflow

.github/workflows/daily-windows-defender-scan.md already downloads the latest release's Windows AMD64 and ARM64 assets, updates signatures, scans them, and stores a structured report for an agentic follow-up.

Important current gaps:

  1. It does not download checksums.txt or compare downloaded assets with the release's published checksums. It only compares each downloaded source file with its temporary scan copy.
  2. It scans only the latest stable release. There is no manual list/range or configurable recent-release lookback for determining exactly where a new signature collision starts and stops.
  3. Its follow-up is oriented toward proposing a source-code fix. A checksum-valid, release-specific AV classification may require a Microsoft false-positive submission and tracking issue rather than a source change or binary obfuscation.
  4. -DisableRemediation applies to the explicit custom scan, but real-time protection can still block or quarantine an executable while it is downloaded or copied. Disappearance of an asset must be captured as evidence and correlated with Defender detection history/event logs.
  5. The release and daily workflows duplicate substantial Defender discovery, signature-update, scan-validation, and reporting logic.

General CI

.github/workflows/ci.yml does not build release-equivalent Windows assets or run Defender. Its Windows coverage is currently the windows-redirect-tests matrix job. Defender signatures are mutable external state, so the recurring released-asset check should not be added indiscriminately to every required PR CI run. If pre-merge scanning is desired, it should be a separate job that builds with the exact release flags and is clearly distinguished from the authoritative release gate.

Proposed implementation

1. Extract a reusable PowerShell scanner

Add a checked-in script, for example .github/scripts/scan-windows-defender.ps1, used by both the release and recurring workflows. It should:

  • Locate MpCmdRun.exe with the existing ProgramFiles/ProgramFiles(x86) fallback.
  • Update signatures with bounded retries and fail closed if updates cannot complete.
  • Record product, engine, and signature versions and protection state.
  • Stabilize and hash each source file before scanning.
  • Copy the file to a dedicated path outside the workspace and verify size and SHA-256 again.
  • Run a custom scan with -DisableRemediation.
  • Require scan-start and scan-finished markers, reject skipped/excluded output, and treat any nonzero exit or threat record as a finding.
  • Retry only known transient service failures such as 0x800106ba.
  • Produce structured JSON plus raw per-binary logs.
  • Correlate findings with Get-MpThreatDetection and/or the Defender operational event log so the report includes the threat name and ID even if real-time protection removes the file before the explicit scan.

2. Keep and strengthen the release gate

Retain the existing defender dependency before publication, but invoke the reusable scanner. Also parse the generated dist/checksums.txt and require every scanned Windows binary to match it before scanning.

3. Strengthen recurring released-asset scans

Extend .github/workflows/daily-windows-defender-scan.md so it:

  • Downloads checksums.txt alongside both Windows assets and verifies each published checksum before scanning.
  • Keeps the daily latest-stable scan.
  • Supports workflow_dispatch inputs for a specific tag and either a list of tags or bounded recent-release count.
  • Optionally scans the most recent stable plus recent prereleases to identify a narrow affected version range.
  • Uploads reports on both success and failure, with a retention period sufficient for signature-change investigations.
  • Includes release tag, release URL, asset name, size, expected/actual SHA-256, scan timestamps, exit code, detection name/ID, Defender versions, and raw output.
  • Opens or updates one deduplicated tracking issue for actionable checksum-valid detections. It must not weaken scanning, add exclusions, disable Defender, obfuscate binaries, or automatically assume a source-code change is appropriate.

4. Keep routine PR CI deterministic

Do not make mutable Defender signatures part of every existing required ci.yml job. If a PR-time scan is added later, make it an isolated, nonduplicative Windows job that consumes a release-equivalent build artifact and uses the same scanner.

Suggested scan contract

For each binary, success requires all of the following:

  1. The asset exists and is stable.
  2. Its SHA-256 matches checksums.txt.
  3. The scan copy matches the source size and SHA-256.
  4. Signature update succeeded.
  5. MpCmdRun.exe emitted both scan-start and scan-finished markers.
  6. The scan was not skipped or excluded.
  7. Exit code is zero.
  8. No threat appears in output, detection history, or correlated Defender events.

Anything else should be reported as a finding, not silently treated as clean.

Acceptance criteria

  • Release-time scanning remains a required prerequisite for publishing a release.
  • Release and recurring jobs share one reviewed PowerShell scan implementation.
  • Both windows-amd64.exe and windows-arm64.exe are checked.
  • Published checksums.txt values are verified before post-release scans.
  • Scheduled latest-release scans continue with freshly updated signatures.
  • Manual scans can target v0.87.10 and a bounded set of recent tags.
  • Reports contain hashes, Defender versions, timestamps, exit codes, detection metadata, and raw logs.
  • Download/copy quarantine races are reported and correlated rather than misclassified as missing files.
  • A checksum-valid Defender detection creates or updates one deduplicated tracking issue with false-positive submission details.
  • No workflow disables Defender, adds exclusions, weakens failure checks, or changes binaries merely to evade a signature.
  • Actions are SHA-pinned in the compiled workflow and permissions remain least-privilege.
  • Focused tests cover checksum parsing and scan-output classification where practical.

Immediate operational follow-up

Submit v0.87.10/windows-amd64.exe to Microsoft's malware-analysis portal as incorrectly detected, using the hash and Defender metadata above, and record the Microsoft submission ID in this issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions