Skip to content

MSDefenderForEndpoint responder - Rename, OAuth v2.0 migration, bug fixes & new action - #1479

Open
3lina wants to merge 1 commit into
TheHive-Project:developfrom
3lina:msdefender-for-endpoint-responders
Open

MSDefenderForEndpoint responder - Rename, OAuth v2.0 migration, bug fixes & new action#1479
3lina wants to merge 1 commit into
TheHive-Project:developfrom
3lina:msdefender-for-endpoint-responders

Conversation

@3lina

@3lina 3lina commented Jul 30, 2026

Copy link
Copy Markdown

Summary

Review of the MSDefender responder against current Microsoft docs: renamed for
consistency with the sibling analyzer, migrated to OAuth v2.0, fixed several bugs
(three only caught by running real jobs against a live Cortex instance), converted to
snake_case, removed a deprecated action, added one new action.

⚠️ Potential breaking changes

  • baseConfig renamed (MSDefenderforEndpointsMSDefenderForEndpoint) — orgs need
    to re-enter credentials.
  • Flavor name renamed on all 12 flavors — each needs re-enabling per org.
  • pushIOCAlert removed because deprecated since 2022 — use pushIOCAudit instead (identical behavior).
  • AddTagToArtifact tags renamed (MsDefender:xxxMSDefenderForEndpoint:xxx).

Not breaking: OAuth migration, snake_case, folder/file rename (all internal), new
stopAndQuarantineFile action (additive).

Bug fixes

  • Duplicate report on isolate could mask a real failure as success.
  • Raw exceptions passed to self.error() broke JSON serialization.
  • Byte-encoded case title leaked b'...' into IOCs sent to Defender.
  • Missing timeouts on HTTP calls.
  • Hash validation checked length only, not hex format.
  • Non-200 API responses silently ignored on machine lookup / IOC push.
  • get_machine_id() returned the wrong ID for hostname lookups — it preferred
    aadDeviceId over the MDE id, but action endpoints require id. Worked by luck
    for IPs, broke for hostnames. Now always returns id.
  • Every self.error() call (~20 sites) passed a dict, making error messages
    invisible in the UI
    cortexutils.Worker.error() expects a plain string, not a
    dict (unlike report(), which does expect one). This was the real cause behind every
    "no error shown" case hit while testing this PR. Fixed everywhere.
  • Generic error branches on 6 machine-action functions now include HTTP status + body.
  • Flavor name typo: FullVirusscanFullVirusScan.

OAuth v1.0 → v2.0

oauth2/tokenoauth2/v2.0/token, resourcescope. Scope stays pinned to
https://api.securitycenter.microsoft.com/.default even though the API host is now
unified (api.security.microsoft.com) — required by current MS docs, otherwise 403.

Python elements renamed for consistency to follow PEP8 convention

Folder/file/class renamed, all 12 flavors renamed, full snake_case conversion (checked
for collisions with wire-protocol strings that must stay as-is — none touched).

Removed: pushIOCAlert

Microsoft's Alert/AlertAndBlock actions are legacy, unsupported since Jan 2022. This
flavor was already an exact duplicate of pushIOCAudit internally.

New action: stopAndQuarantineFile

SHA1-only. Resolves machines via GET /files/{sha1}/machines, then
POST /machines/{id}/StopAndQuarantineFile on each, aggregated report.
Not added: Offboard, CollectInvestigationPackage, LiveResponse, UpdateAlert
(out of scope / not a good fit for a generic responder).

Testing

Tested against a real MDE tenant and TheHive/Cortex local instances.

@nusantara-self nusantara-self self-assigned this Jul 30, 2026
@nusantara-self
nusantara-self changed the base branch from master to develop July 30, 2026 18:08
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.

2 participants