DEV Community

Onizuka
Onizuka

Posted on

Could a WHOIS Audit Stop the Next Supply Chain Attack?

cybersecurity #supplychain #whois #rapidapi #devsecops #domainsecurity #subdomaintakeover

When attackers hit the software supply chain, we usually picture malicious code slipped into a popular package. But the recent Shai-Hulud campaign, which reportedly impacted Keyv and related dependencies, is a reminder that supply-chain attacks often start with infrastructure, not source code. Hijacked subdomains, expired maintainer domains, and weak email-security posture can all become footholds for injecting malicious updates or redirecting users.

A domain and DNS audit won’t patch your code, but it can spot the infrastructure drift that lets these attacks succeed. In this post I’ll show how to use the Domain WHOIS API to audit dependency-related domains, detect subdomain takeover risk, and score email-security posture (SPF, DMARC, DKIM, DNSSEC, MTA-STS) from your CI pipeline.


Why supply-chain attackers love domains and DNS

Most packages list a homepage, documentation site, or author email. If an attacker can:

  • Take over an expired domain tied to a maintainer,
  • Hijack a dangling subdomain that once hosted package docs or a CDN,
  • Spoof a maintainer because DMARC/SPF are missing,

…they can redirect installs, publish fake updates, or phish credentials without ever touching the registry’s source code.

The good news: these weaknesses are visible from public DNS and WHOIS data. The Domain WHOIS API combines RDAP WHOIS, DNS records, SSL certificates, subdomain discovery, takeover-risk scoring, email-security scoring, and historical snapshots in one endpoint.


What the API gives you

A single query can return:

Capability Why it matters for supply-chain defense
RDAP WHOIS Domain age, registrar, expiry, status flags
DNS records A, AAAA, CNAME, MX, TXT (SPF/DMARC/DKIM)
SSL certificate Cert validity, issuer, SANs
Subdomain discovery Shadow infrastructure and dangling hosts
Subdomain takeover risk CNAME chains pointing to unclaimed services
Email-security score SPF, DMARC, DKIM, DNSSEC, MTA-STS
/history snapshots Track when SPF/DMARC or subdomains changed

That is exactly the intelligence you need to turn “trust this domain” into a measurable check.


Auditing dependency-related domains

Let’s build a tiny Python script that scans the domains behind your npm dependencies. It extracts hostnames from resolved/homepage URLs, then queries the API for each one.

import json
import subprocess
import urllib.parse
import requests

RAPIDAPI_KEY = "YOUR_RAPIDAPI_KEY"
API_URL = "https://domain-whois2.p.rapidapi.com/whois"
HEADERS = {
    "x-rapidapi-key": RAPIDAPI_KEY,
    "x-rapidapi-host": "domain-whois2.p.rapidapi.com",
}

def extract_domain(url: str) -> str | None:
    if not url:
        return None
    parsed = urllib.parse.urlparse(url)
    host = parsed.netloc
    if host.startswith("www."):
        host = host[4:]
    return host or None

def audit_domain(domain: str):
    params = {
        "domain": domain,
        "subdomains": "true",
        "takeover": "true",
        "email_security": "true",
    }
    r = requests.get(API_URL, headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()

def main():
    # Pull installed npm dependencies
    npm_ls = subprocess.run(
        ["npm", "ls", "--json", "--silent"],
        capture_output=True, text=True, check=False
    )
    tree = json.loads(npm_ls.stdout or "{}")
    domains = set()

    def walk(node):
        for pkg, info in (node or {}).items():
            if not isinstance(info, dict):
                continue
            for url_field in ("resolved", "homepage"):
                domains.add(extract_domain(info.get(url_field, "")))
            walk(info.get("dependencies", {}))

    walk(tree.get("dependencies", {}))

    print(f"Auditing {len(domains)} unique dependency-related domains...")
    for d in sorted(domains):
        if not d:
            continue
        try:
            report = audit_domain(d)
            whois = report.get("whois", {})
            email = report.get("email_security", {})
            takeovers = report.get("takeover_risk", [])

            flags = []
            if whois.get("domain_age_days", 9999) < 90:
                flags.append("very young domain")
            if whois.get("expiry_date") and "2025" not in str(whois.get("expiry_date")):
                flags.append("check expiry")
            if email.get("score", 0) < 50:
                flags.append("weak email security")
            if takeovers:
                flags.append(f"{len(takeovers)} takeover risks")

            print(f"  {d}: {', '.join(flags) if flags else 'OK'}")
        except Exception as e:
            print(f"  {d}: error ({e})")

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Run it in a repo after npm install and you’ll get a quick risk map of the domains your build pipeline implicitly trusts.


Detecting subdomain takeover risk

Subdomain takeover happens when a DNS CNAME still points to a cloud service (GitHub Pages, Heroku, AWS S3, etc.) that no longer claims the target. The API flags these for you.

Example JSON excerpt:

{
  "takeover_risk": [
    {
      "subdomain": "docs.example-package.dev",
      "cname": "example-package.github.io.",
      "service": "GitHub Pages",
      "claimable": true,
      "http_status": 404
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

If docs.example-package.dev hosts your package README or install instructions, an attacker can register the missing GitHub Pages repo and serve malicious content under your official subdomain. Fix: remove the dangling CNAME or reclaim the cloud resource immediately.


Verifying email-security posture

Package registries and CI systems often email maintainers about publish events, password resets, or security advisories. If a maintainer’s domain lacks SPF, DMARC, DKIM, DNSSEC, or MTA-STS, phishing that domain becomes trivial.

The API returns a normalized score:

report = audit_domain("example.com")
email = report.get("email_security", {})
print(f"Email security score: {email.get('score')}/100")
for check in email.get("checks", []):
    print(f"  {check['name']}: {check['status']}")
Enter fullscreen mode Exit fullscreen mode

Aim for:

  • SPF ~all or -all
  • DMARC p=reject or p=quarantine
  • DKIM valid selector present
  • DNSSEC enabled
  • MTA-STS policy published

How to use Domain WHOIS API

Sign up at the RapidAPI listing: https://rapidapi.com/On13uka/api/domain-whois2, subscribe, and copy your API key.

cURL

curl --request GET \
  --url 'https://domain-whois2.p.rapidapi.com/whois?domain=example.com&subdomains=true&takeover=true&email_security=true' \
  --header 'x-rapidapi-key: YOUR_RAPIDAPI_KEY' \
  --header 'x-rapidapi-host: domain-whois2.p.rapidapi.com'
Enter fullscreen mode Exit fullscreen mode

Python

import requests

url = "https://domain-whois2.p.rapidapi.com/whois"
headers = {
    "x-rapidapi-key": "YOUR_RAPIDAPI_KEY",
    "x-rapidapi-host": "domain-whois2.p.rapidapi.com",
}
params = {
    "domain": "example.com",
    "subdomains": "true",
    "takeover": "true",
    "email_security": "true",
}

r = requests.get(url, headers=headers, params=params)
print(r.json())
Enter fullscreen mode Exit fullscreen mode

For more examples and issue tracking, check the GitHub repo: https://github.com/On13uka/domain-whois-api.


Historical snapshots with /history

Supply-chain infrastructure changes over time. A domain that had strong DMARC last quarter might drop it today. Use the /history endpoint to diff email-security and subdomain states:

curl --request GET \
  --url 'https://domain-whois2.p.rapidapi.com/history?domain=example.com&days=90' \
  --header 'x-rapidapi-key: YOUR_RAPIDAPI_KEY' \
  --header 'x-rapidapi-host: domain-whois2.p.rapidapi.com'
Enter fullscreen mode Exit fullscreen mode

Store these diffs in a security dashboard and alert when SPF/DMARC degrade or new subdomains appear.


Conclusion

The Shai-Hulud/Keyv incident is another wake-up call: supply-chain security is not just about code signing and dependency pinning. Attackers exploit the edges of the software ecosystem—expired domains, dangling subdomains, and weak email authentication.

Adding a Domain WHOIS API audit to your CI/CD or threat-intel pipeline gives you a low-noise, high-signal way to catch those infrastructure risks before they become backdoors. Start by auditing the domains behind your top dependencies, flag takeover risks, and enforce a minimum email-security score. It won’t stop every attack—but it will close a door that too many attackers still find wide open.

Top comments (0)