Skip to content

Commit 38ba0ab

Browse files
committed
refactor: remove text report generation for CF1016 and update scan results API to skip parsing legacy output files
1 parent 9a3a89e commit 38ba0ab

2 files changed

Lines changed: 4 additions & 101 deletions

File tree

internal/modules/cf1016/cf1016.go

Lines changed: 2 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ type Options struct {
9494
// Result holds the outcome of the scan.
9595
type Result struct {
9696
Findings []Finding
97-
Output string // path to the output file
9897
}
9998

10099
// Run scans the subdomains for dangling Cloudflare 1016 records.
@@ -122,13 +121,7 @@ func Run(opts Options) (*Result, error) {
122121

123122
findings := scanConcurrent(subdomains, opts.Threads, opts.Timeout)
124123

125-
// Write output
126-
outputPath, err := writeOutput(opts, findings)
127-
if err != nil {
128-
log.Printf("[cf1016] Warning: could not write output file: %v", err)
129-
}
130-
131-
// Write structured JSON alongside the text report for the dashboard.
124+
// Write structured JSON results for the dashboard.
132125
if scanID := os.Getenv("AUTOAR_CURRENT_SCAN_ID"); scanID != "" {
133126
jsonPath := filepath.Join(utils.GetScanResultsDir(scanID), "cf1016-vulnerabilities.json")
134127
if len(findings) > 0 {
@@ -166,7 +159,7 @@ func Run(opts Options) (*Result, error) {
166159

167160
log.Printf("[cf1016] Done. Found %d dangling Cloudflare 1016 records", len(findings))
168161

169-
return &Result{Findings: findings, Output: outputPath}, nil
162+
return &Result{Findings: findings}, nil
170163
}
171164

172165
// ------------------------ helpers ------------------------
@@ -354,96 +347,6 @@ func checkSubdomain(subdomain string, timeout time.Duration) (Finding, bool) {
354347
}, true
355348
}
356349

357-
func writeOutput(opts Options, findings []Finding) (string, error) {
358-
outDir := opts.OutputDir
359-
if outDir == "" {
360-
resultsDir := os.Getenv("AUTOAR_RESULTS_DIR")
361-
if resultsDir == "" {
362-
resultsDir = "new-results"
363-
}
364-
domain := opts.Domain
365-
if domain == "" {
366-
domain = "unknown"
367-
}
368-
outDir = filepath.Join(resultsDir, domain, "vulnerabilities", "cf1016")
369-
}
370-
371-
if err := os.MkdirAll(outDir, 0o755); err != nil {
372-
return "", err
373-
}
374-
375-
outputPath := filepath.Join(outDir, "cf1016-dangling.txt")
376-
377-
f, err := os.Create(outputPath)
378-
if err != nil {
379-
return "", err
380-
}
381-
defer f.Close()
382-
383-
if len(findings) == 0 {
384-
fmt.Fprintln(f, "# No Cloudflare 1016 dangling records found.")
385-
return outputPath, nil
386-
}
387-
388-
fmt.Fprintf(f, "# Cloudflare 1016 Dangling DNS Records\n")
389-
fmt.Fprintf(f, "# Vulnerability Type: DNS Misconfiguration / Dangling Record\n")
390-
fmt.Fprintf(f, "# Found: %d subdomains\n", len(findings))
391-
fmt.Fprintf(f, "# Generated: %s\n\n", time.Now().UTC().Format(time.RFC3339))
392-
393-
fmt.Fprintf(f, "%-60s %-40s %s\n", "Subdomain", "Cloudflare IPs", "HTTP Status")
394-
fmt.Fprintf(f, "%s %s %s\n", strings.Repeat("-", 60), strings.Repeat("-", 40), strings.Repeat("-", 11))
395-
396-
for _, finding := range findings {
397-
fmt.Fprintf(f, "%-60s %-40s %d\n",
398-
finding.Subdomain,
399-
strings.Join(finding.IPs, ", "),
400-
finding.StatusCode,
401-
)
402-
}
403-
404-
fmt.Fprintf(f, "\n\n# --- Report Template ---\n")
405-
for _, finding := range findings {
406-
fmt.Fprintf(f, `
407-
## Dangling DNS Record / Origin Resolution Error (Cloudflare 1016)
408-
**Subdomain:** %s
409-
**Cloudflare IPs:** %s
410-
**HTTP Status:** %d
411-
412-
**Vulnerability Type:** DNS Misconfiguration / Dangling Record
413-
414-
**Summary:**
415-
The subdomain %s is currently resolving to Cloudflare's edge network, but HTTP
416-
requests return Cloudflare Error 1016 (Origin DNS Error). The DNS record still
417-
actively routes traffic through Cloudflare, but the underlying backend origin
418-
has been deleted, deactivated, or misconfigured.
419-
420-
**Steps To Reproduce:**
421-
1. dig %s (resolves to Cloudflare IPs: %s)
422-
2. curl https://%s/ (observe error code: 1016)
423-
424-
**Impact:**
425-
If an attacker can claim the abandoned origin resource, they could hijack this
426-
subdomain via Cloudflare's proxy — enabling phishing, cookie theft, or session
427-
hijacking against users of the target organization.
428-
429-
**Recommended Mitigation:**
430-
Remove the A/CNAME records for %s from your DNS zone to clean up the dangling record.
431-
`,
432-
finding.Subdomain,
433-
strings.Join(finding.IPs, ", "),
434-
finding.StatusCode,
435-
finding.Subdomain,
436-
finding.Subdomain,
437-
strings.Join(finding.IPs, ", "),
438-
finding.Subdomain,
439-
finding.Subdomain,
440-
)
441-
}
442-
443-
log.Printf("[cf1016] Wrote %d findings to %s", len(findings), outputPath)
444-
return outputPath, nil
445-
}
446-
447350
// writeJSONOutput writes a structured JSON file suitable for the dashboard
448351
// parsedFindings pipeline. One JSON object per vulnerable subdomain.
449352
func writeJSONOutput(path string, findings []Finding) error {

internal/modules/gobot/scan_results_api.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,8 +1126,8 @@ func apiScanParsedResults(c *gin.Context) {
11261126
"cloudflare-tunnel-errors.txt": "dns-takeover-vulnerabilities.json",
11271127
"cname-takeover-raw.txt": "dns-takeover-vulnerabilities.json",
11281128
"cname-takeover-vulnerable.txt": "dns-takeover-vulnerabilities.json",
1129-
// CF1016 text report is superseded by the structured JSON twin
1130-
"cf1016-dangling.txt": "cf1016-dangling.json",
1129+
// CF1016 text report is for human reading only — skip line-by-line finding parsing
1130+
"cf1016-dangling.txt": "__pipeline_input__",
11311131
}
11321132

11331133
for _, e := range entries {

0 commit comments

Comments
 (0)