fix: critical bug - exploitation phase was always skipped

ROOT CAUSE:
- Exploitation phase checked session.validationResults to determine eligibility
- validationResults field was removed during audit system refactor
- Field never existed in session schema, so all exploits were skipped

THE FIX:
- Exploitation phase now validates queue files directly when checking eligibility
- Reads exploitation_queue.json and checks if vulnerabilities array is non-empty
- No need to store validation results - just re-validate on demand

CHANGES:
1. runParallelExploit() now calls safeValidateQueueAndDeliverable() directly
2. Removed validationResults parameter from markAgentCompleted()
3. Simplified calculateVulnerabilityAnalysisSummary() - no longer needs validation data
4. Simplified calculateExploitationSummary() - no longer needs validation data

IMPACT:
- Exploitation agents will now run when vulnerabilities are found
- Queue files are the single source of truth for eligibility
- Simpler architecture - no duplicate state storage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ajmallesh
2025-10-22 17:41:41 -07:00
parent 255956d113
commit cfe8dc8bc8
2 changed files with 37 additions and 46 deletions
+6 -26
View File
@@ -552,25 +552,12 @@ export const getSessionStatus = (session) => {
export const calculateVulnerabilityAnalysisSummary = (session) => {
const vulnAgents = PHASES['vulnerability-analysis'];
const completedVulnAgents = session.completedAgents.filter(agent => vulnAgents.includes(agent));
const validationResults = session.validationResults || {};
let totalVulnerabilities = 0;
let agentsWithVulns = 0;
for (const agent of completedVulnAgents) {
const validation = validationResults[agent];
if (validation?.vulnerabilityCount > 0) {
totalVulnerabilities += validation.vulnerabilityCount;
agentsWithVulns++;
}
}
// NOTE: Actual vulnerability counts require reading queue files
// This summary only shows completion counts
return Object.freeze({
totalAnalyses: completedVulnAgents.length,
totalVulnerabilities,
agentsWithVulnerabilities: agentsWithVulns,
successRate: completedVulnAgents.length > 0 ? (agentsWithVulns / completedVulnAgents.length) * 100 : 0,
exploitationCandidates: Object.values(validationResults).filter(v => v?.shouldExploit).length
completedAgents: completedVulnAgents
});
};
@@ -578,19 +565,12 @@ export const calculateVulnerabilityAnalysisSummary = (session) => {
export const calculateExploitationSummary = (session) => {
const exploitAgents = PHASES['exploitation'];
const completedExploitAgents = session.completedAgents.filter(agent => exploitAgents.includes(agent));
const validationResults = session.validationResults || {};
// Count how many exploitation agents were eligible to run
const eligibleExploits = exploitAgents.filter(agentName => {
const vulnAgentName = agentName.replace('-exploit', '-vuln');
return validationResults[vulnAgentName]?.shouldExploit;
});
// NOTE: Eligibility requires reading queue files
// This summary only shows completion counts
return Object.freeze({
totalAttempts: completedExploitAgents.length,
eligibleExploits: eligibleExploits.length,
skippedExploits: eligibleExploits.length - completedExploitAgents.length,
successRate: eligibleExploits.length > 0 ? (completedExploitAgents.length / eligibleExploits.length) * 100 : 0
completedAgents: completedExploitAgents
});
};