GitHub Webhook Created or Configuration Changed

Detects creation or configuration change of a GitHub webhook. Attackers can add a hook to copy push, pull request, and workflow payloads (including secrets that land in those events) to an external URL.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/09/22"
  3integration = ["github"]
  4maturity = "production"
  5updated_date = "2026/11/03"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects creation or configuration change of a GitHub webhook. Attackers can add a hook to copy push, pull request, and
 11workflow payloads (including secrets that land in those events) to an external URL.
 12"""
 13false_positives = [
 14    """
 15    Installing a documented CI, chat, or ticketing integration that uses GitHub webhooks. Confirm the payload URL and
 16    subscribed events with the repository owners.
 17    """,
 18]
 19from = "now-9m"
 20language = "esql"
 21license = "Elastic License v2"
 22name = "GitHub Webhook Created or Configuration Changed"
 23note = """## Triage and analysis
 24
 25### Investigating GitHub Webhook Created or Configuration Changed
 26
 27`hook.create` adds a webhook. `hook.config_changed` updates the payload URL or other hook settings. Either action can send repository events to an attacker-controlled endpoint.
 28
 29### Possible investigation steps
 30
 31- Identify `user.name`, `github.repo`, `github.actor_ip`, and `github.programmatic_access_type`.
 32- In repository Settings → Webhooks, inspect the payload URL, content type, and subscribed events. Treat unknown hosts as compromised.
 33- Pivot to `git.push`, `repo.download_zip`, and Actions secret creates by the same actor.
 34
 35### False positive analysis
 36
 37- First-time install of Slack, Jira, or a deploy bot that registers a webhook.
 38- Terraform or GitHub App automation that manages hooks.
 39
 40### Response and remediation
 41
 42- Delete unauthorized webhooks. Rotate secrets that may have been delivered in payloads.
 43- Revoke the actor's tokens if the hook was not approved.
 44"""
 45references = [
 46    "https://docs.github.com/en/webhooks/about-webhooks",
 47    "https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/audit-log-events-for-your-organization",
 48]
 49risk_score = 21
 50rule_id = "ac34a5d9-352e-434a-8a17-dc55a49ee740"
 51severity = "low"
 52tags = [
 53    "Domain: Cloud",
 54    "Domain: SaaS",
 55    "Platform: GitHub",
 56    "Use Case: Threat Detection",
 57    "Tactic: Collection",
 58    "Tactic: Exfiltration",
 59    "Data Source: Github",
 60    "Data Source: GitHub Audit Logs",
 61    "Rule Type: ES|QL",
 62    "Resources: Investigation Guide",
 63]
 64timestamp_override = "event.ingested"
 65type = "esql"
 66
 67query = '''
 68from logs-github.audit-* metadata _id, _index, _version
 69| where
 70  data_stream.dataset == "github.audit"
 71    and (github.actor_is_bot is not null and github.actor_is_bot == false)
 72    and event.action in ("hook.create", "hook.config_changed")
 73| keep
 74    _id,
 75    _index,
 76    _version,
 77    @timestamp,
 78    event.action,
 79    user.name,
 80    github.org,
 81    github.repo,
 82    github.actor_ip,
 83    github.hashed_token,
 84    github.programmatic_access_type,
 85    github.user_agent,
 86    github.hook_id,
 87    github.name,
 88    github.actor_is_bot
 89'''
 90
 91
 92[[rule.threat]]
 93framework = "MITRE ATT&CK"
 94[[rule.threat.technique]]
 95id = "T1213"
 96name = "Data from Information Repositories"
 97reference = "https://attack.mitre.org/techniques/T1213/"
 98[[rule.threat.technique.subtechnique]]
 99id = "T1213.003"
100name = "Code Repositories"
101reference = "https://attack.mitre.org/techniques/T1213/003/"
102
103
104
105[rule.threat.tactic]
106id = "TA0009"
107name = "Collection"
108reference = "https://attack.mitre.org/tactics/TA0009/"
109[[rule.threat]]
110framework = "MITRE ATT&CK"
111[[rule.threat.technique]]
112id = "T1567"
113name = "Exfiltration Over Web Service"
114reference = "https://attack.mitre.org/techniques/T1567/"
115[[rule.threat.technique.subtechnique]]
116id = "T1567.004"
117name = "Exfiltration Over Webhook"
118reference = "https://attack.mitre.org/techniques/T1567/004/"
119
120
121[rule.threat.tactic]
122id = "TA0010"
123name = "Exfiltration"
124reference = "https://attack.mitre.org/tactics/TA0010/"
125
126[rule.investigation_fields]
127field_names = [
128    "@timestamp",
129    "event.action",
130    "user.name",
131    "github.org",
132    "github.repo",
133    "github.actor_ip",
134    "github.hashed_token",
135    "github.programmatic_access_type",
136    "github.user_agent",
137    "github.hook_id",
138    "github.name",
139    "github.actor_is_bot",
140]

Triage and analysis

Investigating GitHub Webhook Created or Configuration Changed

hook.create adds a webhook. hook.config_changed updates the payload URL or other hook settings. Either action can send repository events to an attacker-controlled endpoint.

Possible investigation steps

  • Identify user.name, github.repo, github.actor_ip, and github.programmatic_access_type.
  • In repository Settings → Webhooks, inspect the payload URL, content type, and subscribed events. Treat unknown hosts as compromised.
  • Pivot to git.push, repo.download_zip, and Actions secret creates by the same actor.

False positive analysis

  • First-time install of Slack, Jira, or a deploy bot that registers a webhook.
  • Terraform or GitHub App automation that manages hooks.

Response and remediation

  • Delete unauthorized webhooks. Rotate secrets that may have been delivered in payloads.
  • Revoke the actor's tokens if the hook was not approved.

References

Related rules

to-top