Skip to content

Commit

Permalink
feat: add dangling DNS record check (#425)
Browse files Browse the repository at this point in the history
Add a scheduled workflow that will extract A, CNAME and NS records
from the Terraform and check if any are vulnerable to takeover.
  • Loading branch information
patheard authored Oct 11, 2024
1 parent 8136839 commit 68fe9e3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/dangling-dns-record.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Dangling DNS record check

on:
workflow_dispatch:
schedule:
- cron: '0 13 * * *'

permissions:
contents: read

jobs:
check-dns-records:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0

- name: Get DNS records from Terraform
run: |
./bin/get-dns-records.sh ./terraform | sort | uniq > domains.txt
- name: Check DNS records
uses: maxneuvians/dns-hijack-check-action@main

- name: Notify if dangling records found
if: ${{ hashFiles('critical.json') != '' || hashFiles('potential.json') != '' }}
run: |
json='{"text":":dumpster-fire: Dangling DNS records found in `cds-snc/dns`: <https://github.com/cds-snc/dns/actions/workflows/dangling-dns-record.yml|view workflow>"}'
curl -X POST -H 'Content-type: application/json' --data "$json" ${{ secrets.SLACK_INTERNAL_SRE_ALERTS }}
40 changes: 40 additions & 0 deletions bin/get-dns-records.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

#
# Retrieve A, CNAME and NS records from Terraform files.
#

# Directory containing Terraform files
TERRAFORM_DIR="$1"

# Domains to extract records for
DOMAINS=("cds-snc.ca" "canada.ca")

# Function to extract records by type
extract_records() {
local file=$1
local record_type=$2
local domains_regex=$(IFS="|"; echo "${DOMAINS[*]}")

awk -v type="$record_type" -v domains="$domains_regex" '
/resource "aws_route53_record"/ {in_resource = 1; record_name = ""; record_type = ""; next}
in_resource && /name *=/ {record_name = $3; gsub(/"/, "", record_name); next}
in_resource && /type *=/ {record_type = $3; next}
in_resource && /}/ {
in_resource = 0;
if (record_type == "\"" type "\"" && record_name ~ "(" domains ")$") {
print record_name
}
next
}
' "$file"
}

# Loop through all Terraform files in the directory
for file in "$TERRAFORM_DIR"/*.tf; do
extract_records "$file" "A"
extract_records "$file" "CNAME"
extract_records "$file" "NS"
done

0 comments on commit 68fe9e3

Please sign in to comment.