feat: show 'Could Not Scan Target' message when GoTestWAF fails, instead of misleading fallback score
This commit is contained in:
parent
2ba2bd6c76
commit
692714402a
4 changed files with 59 additions and 6 deletions
BIN
aasd/bin/aasd
BIN
aasd/bin/aasd
Binary file not shown.
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue