From 07d72290807093cbe012505f74667a67a2eb8275 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 23 Oct 2026 13:16:42 +0200 Subject: [PATCH 01/11] add CI that verifies GitHub IPv4 ranges that send webhooks - runs daily at 06:42 UTC - runs for every opened PR - can be run on request --- .github/workflows/github_hooks_ip_ranges.yml | 47 +++++++++++++++++++ .../workflows/github_hooks_ip_ranges_file.cfg | 7 +++ 2 files changed, 54 insertions(+) create mode 100644 .github/workflows/github_hooks_ip_ranges.yml create mode 100644 .github/workflows/github_hooks_ip_ranges_file.cfg diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml new file mode 100644 index 0000000000..7c58c936eb --- /dev/null +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -0,0 +1,47 @@ +name: Check GitHub webhook IP ranges + +on: + schedule: + - cron: "42 6 * * *" # daily, 06:42 UTC + workflow_dispatch: + pull_request: + types: [opened] + +permissions: + contents: read + +env: + # Path (in this repo) to the file listing the GitHub IP ranges we accept webhooks from + GITHUB_WEBHOOK_IP_RANGES_FILE: .github/workflows/github_hooks_ip_ranges_file.cfg + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Compare GitHub hooks ranges with accepted webhook IPv4 ranges + run: | + set -euo pipefail + + curl -fsSL https://api.github.com/meta \ + | jq -r '.hooks[] | select(contains(":") | not)' \ + | sort -u > current_ip_ranges_hooks_are_sent_from.txt + + echo "Current GitHub hooks IPv4 ranges:" + cat current_ip_ranges_hooks_are_sent_from.txt + + missing=0 + while read -r cidr; do + if ! grep -qF "\"$cidr\"" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then + echo "::error::Missing from accepted GitHub webhook IP ranges: $cidr" + missing=1 + fi + done < current_ip_ranges_hooks_are_sent_from.txt + + if [ "$missing" -eq 1 ]; then + echo "Accepted GitHub webhook IPv4 ranges are out of date. Add the ranges above to $GITHUB_WEBHOOK_IP_RANGES_FILE." + exit 1 + fi + echo "All current GitHub hooks IPv4 ranges are accepted." diff --git a/.github/workflows/github_hooks_ip_ranges_file.cfg b/.github/workflows/github_hooks_ip_ranges_file.cfg new file mode 100644 index 0000000000..e10a072195 --- /dev/null +++ b/.github/workflows/github_hooks_ip_ranges_file.cfg @@ -0,0 +1,7 @@ +140.82.112.0/20 +143.55.64.0/20 +185.199.108.0/22 +192.30.252.0/22 +9.234.106.48/28 +9.234.98.160/28 +9.234.98.176/28 From 0388c54074291cb84c708b112b9d285eab939c8c Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 23 Oct 2026 13:26:21 +0200 Subject: [PATCH 02/11] fix grep command by removing quotes in search pattern --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 7c58c936eb..59d3132c20 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -34,7 +34,7 @@ jobs: missing=0 while read -r cidr; do - if ! grep -qF "\"$cidr\"" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then + if ! grep -qF "$cidr" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then echo "::error::Missing from accepted GitHub webhook IP ranges: $cidr" missing=1 fi From 7c12b779ac199bfb5d12298e29f437030bd59026 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 23 Oct 2026 13:32:41 +0200 Subject: [PATCH 03/11] need to match a whole line by adding -x as arg --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 59d3132c20..32de0d0af0 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -34,7 +34,7 @@ jobs: missing=0 while read -r cidr; do - if ! grep -qF "$cidr" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then + if ! grep -qxF "$cidr" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then echo "::error::Missing from accepted GitHub webhook IP ranges: $cidr" missing=1 fi From 46a6e04749186763f45c77a86f534daed6f72d2c Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 23 Oct 2026 13:37:27 +0200 Subject: [PATCH 04/11] temporarily add synchronize as trigger to test whether it works --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 32de0d0af0..f3565ca446 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -5,7 +5,7 @@ on: - cron: "42 6 * * *" # daily, 06:42 UTC workflow_dispatch: pull_request: - types: [opened] + types: [opened, synchronize] permissions: contents: read From e72c045eb9c4c84a3b2368b85ea80c02c6d80547 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 23 Oct 2026 13:42:56 +0200 Subject: [PATCH 05/11] remove synchronize trigger for CI check --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index f3565ca446..32de0d0af0 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -5,7 +5,7 @@ on: - cron: "42 6 * * *" # daily, 06:42 UTC workflow_dispatch: pull_request: - types: [opened, synchronize] + types: [opened] permissions: contents: read From 6fe3243d08b8a74a652913f20a0e9f900f85054b Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:15:08 +0100 Subject: [PATCH 06/11] also check if all accepted IPv4 ranges are used bu GitHub --- .github/workflows/github_hooks_ip_ranges.yml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 32de0d0af0..e256995c58 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -33,9 +33,9 @@ jobs: cat current_ip_ranges_hooks_are_sent_from.txt missing=0 - while read -r cidr; do - if ! grep -qxF "$cidr" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then - echo "::error::Missing from accepted GitHub webhook IP ranges: $cidr" + while read -r github_cidr; do + if ! grep -qxF "$github_cidr" "$GITHUB_WEBHOOK_IP_RANGES_FILE"; then + echo "::error::Missing from accepted GitHub webhook IP ranges: $github_cidr" missing=1 fi done < current_ip_ranges_hooks_are_sent_from.txt @@ -45,3 +45,17 @@ jobs: exit 1 fi echo "All current GitHub hooks IPv4 ranges are accepted." + + additional=0 + while read -r accepted_cidr; do + if ! grep -qxF "$accepted_cidr" current_ip_ranges_hooks_are_sent_from.txt; then + echo "::error::Accepted IPv4 range, but not used by GitHub: $accepted_cidr" + additional=1 + fi + done < "$GITHUB_WEBHOOK_IP_RANGES_FILE" + + if [ "$additional" -eq 1 ]; then + echo "Accepted GitHub webhook IPv4 ranges are out of date. Remove the ranges above from $GITHUB_WEBHOOK_IP_RANGES_FILE." + exit 1 + fi + echo "All currently acceptes IPv4 ranges are used by GitHub to send hooks from." From 3c13518831fdfc19dfa88888afa17efd680c66ae Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:16:24 +0100 Subject: [PATCH 07/11] add 127.0.0.1/32 as range to verify if reverse test fails --- .github/workflows/github_hooks_ip_ranges_file.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github_hooks_ip_ranges_file.cfg b/.github/workflows/github_hooks_ip_ranges_file.cfg index e10a072195..503b9e1772 100644 --- a/.github/workflows/github_hooks_ip_ranges_file.cfg +++ b/.github/workflows/github_hooks_ip_ranges_file.cfg @@ -5,3 +5,4 @@ 9.234.106.48/28 9.234.98.160/28 9.234.98.176/28 +127.0.0.1/32 From 85ec33749a1f4cb96f6fede3f9012514a6c29af0 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:19:22 +0100 Subject: [PATCH 08/11] add synchronize to trigger CI --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index e256995c58..34d230024b 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -5,7 +5,7 @@ on: - cron: "42 6 * * *" # daily, 06:42 UTC workflow_dispatch: pull_request: - types: [opened] + types: [opened, synchronize] permissions: contents: read From 2cd935ff34b23d986c4cc1cd5a7beac5a4ef8dd5 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:23:25 +0100 Subject: [PATCH 09/11] remove additional IPv4 range not used by GitHub --- .github/workflows/github_hooks_ip_ranges_file.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges_file.cfg b/.github/workflows/github_hooks_ip_ranges_file.cfg index 503b9e1772..e10a072195 100644 --- a/.github/workflows/github_hooks_ip_ranges_file.cfg +++ b/.github/workflows/github_hooks_ip_ranges_file.cfg @@ -5,4 +5,3 @@ 9.234.106.48/28 9.234.98.160/28 9.234.98.176/28 -127.0.0.1/32 From f9a361318bc0b736d21fb6c955f330cde8ef0f9c Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:25:58 +0100 Subject: [PATCH 10/11] fix typo --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 34d230024b..01b19023f9 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -58,4 +58,4 @@ jobs: echo "Accepted GitHub webhook IPv4 ranges are out of date. Remove the ranges above from $GITHUB_WEBHOOK_IP_RANGES_FILE." exit 1 fi - echo "All currently acceptes IPv4 ranges are used by GitHub to send hooks from." + echo "All currently accepted IPv4 ranges are used by GitHub to send hooks from." From 95e56348977a5a728b2c2a0a86d9783fb57a1067 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Tue, 27 Oct 2026 14:28:39 +0100 Subject: [PATCH 11/11] remove synchronize trigger --- .github/workflows/github_hooks_ip_ranges.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_hooks_ip_ranges.yml b/.github/workflows/github_hooks_ip_ranges.yml index 01b19023f9..751c072b5d 100644 --- a/.github/workflows/github_hooks_ip_ranges.yml +++ b/.github/workflows/github_hooks_ip_ranges.yml @@ -5,7 +5,7 @@ on: - cron: "42 6 * * *" # daily, 06:42 UTC workflow_dispatch: pull_request: - types: [opened, synchronize] + types: [opened] permissions: contents: read