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>
|
||||||
</div>`, domain, len(subdomains), list)
|
</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")
|
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)
|
result.Error = fmt.Sprintf("scan error: %v", scanErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 3: AI Narrative Generation
|
// Phase 3: Narrative Generation
|
||||||
o.updateStatus(result.ReportToken, StatusGenerating)
|
o.updateStatus(result.ReportToken, StatusGenerating)
|
||||||
var aiHTML string
|
var aiHTML string
|
||||||
var aiErr error
|
|
||||||
if o.aiClient != nil && len(consultantHTML) > 0 {
|
if scanErr != nil {
|
||||||
aiHTML, aiErr = o.aiClient.GenerateResilienceReport(string(consultantHTML))
|
// GoTestWAF failed — explain why the target couldn't be scanned
|
||||||
}
|
aiHTML = report.GenerateScanFailedHTML(result.SelectedDomain, scanErr.Error())
|
||||||
if o.aiClient == nil || len(consultantHTML) == 0 || aiErr != nil {
|
} 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)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No AI client — show summary-based report
|
||||||
aiHTML = report.GenerateFallbackHTML(result.Subdomains)
|
aiHTML = report.GenerateFallbackHTML(result.Subdomains)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue