feat: show 'Could Not Scan Target' message when GoTestWAF fails, instead of misleading fallback score

This commit is contained in:
administrator 2026-04-29 10:31:29 +00:00
parent 2ba2bd6c76
commit 692714402a
4 changed files with 59 additions and 6 deletions

Binary file not shown.

View file

@ -171,3 +171,22 @@ func GenerateFallbackHTML(subdomains []string) string {
</div>
</div>`, domain, len(subdomains), list)
}
// GenerateScanFailedHTML creates a report explaining that the target
// could not be scanned by GoTestWAF (e.g. not an API endpoint).
func GenerateScanFailedHTML(domain, reason string) string {
return fmt.Sprintf(`<div class="bg-gray-900 text-gray-100 p-6 rounded-xl text-center">
<div class="text-5xl mb-4">🔍</div>
<h2 class="text-2xl font-bold text-yellow-400 mb-3">Could Not Scan Target</h2>
<p class="text-gray-300 mb-4">The scanner was unable to assess <strong class="text-white">%s</strong>.</p>
<div class="bg-gray-800 rounded-xl p-4 mb-4 text-left">
<p class="text-sm text-gray-400">The WAF scanner (GoTestWAF) could not process this target. This typically happens when:</p>
<ul class="text-sm text-gray-300 mt-2 space-y-1 list-disc list-inside">
<li>The target is not an API endpoint (e.g. a website or blog)</li>
<li>The target is behind a strict WAF or CDN that blocks scan traffic</li>
<li>The target is unreachable or returns unexpected responses</li>
</ul>
</div>
<p class="text-xs text-gray-500">Try scanning a different subdomain or an API-specific endpoint.</p>
</div>`, domain)
}

View file

@ -307,3 +307,30 @@ func TestGenerateFallbackHTML_ValidHTML(t *testing.T) {
t.Error("expected closing div tag")
}
}
func TestGenerateScanFailedHTML_ContainsDomain(t *testing.T) {
html := GenerateScanFailedHTML("blog.example.com", "exit status 1")
if !strings.Contains(html, "blog.example.com") {
t.Error("expected HTML to contain the domain")
}
}
func TestGenerateScanFailedHTML_Message(t *testing.T) {
html := GenerateScanFailedHTML("example.com", "any error")
if !strings.Contains(html, "Could Not Scan Target") {
t.Error("expected 'Could Not Scan Target' heading")
}
if !strings.Contains(html, "not an API endpoint") {
t.Error("expected explanation about API endpoints")
}
}
func TestGenerateScanFailedHTML_ValidHTML(t *testing.T) {
html := GenerateScanFailedHTML("test.com", "some error")
if !strings.HasPrefix(strings.TrimSpace(html), "<div") {
t.Error("expected HTML to start with a div")
}
if !strings.Contains(html, "</div>") {
t.Error("expected closing div tag")
}
}

View file

@ -179,14 +179,21 @@ func (o *Orchestrator) executeScanPhase(ctx context.Context, result *ScanResult)
result.Error = fmt.Sprintf("scan error: %v", scanErr)
}
// Phase 3: AI Narrative Generation
// Phase 3: Narrative Generation
o.updateStatus(result.ReportToken, StatusGenerating)
var aiHTML string
var aiErr error
if o.aiClient != nil && len(consultantHTML) > 0 {
aiHTML, aiErr = o.aiClient.GenerateResilienceReport(string(consultantHTML))
if scanErr != nil {
// GoTestWAF failed — explain why the target couldn't be scanned
aiHTML = report.GenerateScanFailedHTML(result.SelectedDomain, scanErr.Error())
} else if o.aiClient != nil && len(consultantHTML) > 0 {
// GoTestWAF succeeded — try AI narrative, fall back to summary on failure
aiHTML, _ = o.aiClient.GenerateResilienceReport(string(consultantHTML))
if aiHTML == "" {
aiHTML = report.GenerateFallbackHTML(result.Subdomains)
}
if o.aiClient == nil || len(consultantHTML) == 0 || aiErr != nil {
} else {
// No AI client — show summary-based report
aiHTML = report.GenerateFallbackHTML(result.Subdomains)
}