mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-10-08 17:11:39 +02:00
v4.2.2: validation keeps reproducible findings, /pocs command, version bump
Field feedback: real, reproducible findings (missing HSTS, insecure cookie flags, internal IP leaked in a header) were being down-rated/dropped by the adversarial opinion-vote. The user's rule: never discard something real; another person must be able to reproduce the same finding. Validation: - has_http_receipt(): a finding whose proof is a captured HTTP response (status line / security headers / Set-Cookie / a header the class is proven by) or a file:line citation is REPRODUCIBLE by definition. - validate(): a finding unanimously rejected by the vote but carrying such a receipt is NO LONGER dropped — it is kept as needs-review (capped to what the receipt alone proves), because "the response lacks HSTS" is a fact, not a story. grounded_receipt() now also recognizes an in-prose HTTP receipt. - reproducibility: a kept finding at a URL with no explicit repro steps gets a minimal pasteable `curl -i` so anyone can reproduce the exact finding. Also: - /pocs (aliases /poc /evidence /artifacts): list a run's synthesized/written PoC + evidence files with their paths (was: "unknown command /pocs"). - version bumped to 4.2.2 across CLI/clap/web; stale v4.2.1/v4.1.0 labels fixed. 423 tests passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
45ad7bf359
commit
b55778d6f6
9 files changed
+141
-34
No files matched your search
@@ -148,7 +148,7 @@ struct LiveCheckpoint {
|
||||
pub(crate) const ACCEPTED: &[&str] = &[
|
||||
"/?", "/agents", "/attach", "/audit", "/auth", "/burp", "/cap", "/capability", "/chain", "/changed", "/clear", "/config",
|
||||
"/context", "/continue", "/creds", "/diff", "/exclude", "/exit", "/expand", "/feed",
|
||||
"/finding", "/findings", "/focus", "/forget", "/full", "/go", "/goal", "/graph", "/guardrail", "/guardrails", "/help",
|
||||
"/pocs", "/poc", "/evidence", "/artifacts", "/finding", "/findings", "/focus", "/forget", "/full", "/go", "/goal", "/graph", "/guardrail", "/guardrails", "/help",
|
||||
"/history", "/idle", "/inscope", "/instructions", "/integration", "/integrations", "/key", "/log",
|
||||
"/authorize", "/grant", "/inscope-set", "/scope-file", "/scopefile", "/import-scope", "/authorization", "/authz", "/program", "/logs", "/mcp", "/memory", "/model", "/models", "/objective", "/objectives", "/observe",
|
||||
"/observe-only", "/offline",
|
||||
@@ -164,7 +164,7 @@ const COMMANDS: &[&str] = &[
|
||||
"/help", "/onboard", "/show", "/config", "/providers", "/model", "/key", "/sub", "/target",
|
||||
"/scope-file", "/authorization", "/class", "/repo", "/auth", "/creds", "/focus", "/objective", "/scope-out", "/attach", "/context", "/mcp", "/offline",
|
||||
"/class", "/research", "/quick", "/economy", "/eco", "/votes", "/chain", "/recon", "/tempmail", "/timeout", "/proxy", "/burp", "/ua", "/agents", "/only", "/theme", "/clear", "/run", "/stop", "/pause", "/continue", "/runs", "/results", "/report",
|
||||
"/status", "/logs", "/diff", "/retest", "/validate", "/finding", "/expand", "/integrations",
|
||||
"/status", "/logs", "/diff", "/retest", "/validate", "/finding", "/pocs", "/expand", "/integrations",
|
||||
"/memory", "/forget", "/graph", "/inscope", "/observe", "/guardrail", "/policy",
|
||||
"/capability", "/audit", "/quit",
|
||||
];
|
||||
@@ -1277,6 +1277,31 @@ pub async fn repl(base: &Path, auth: SessionAuth) -> anyhow::Result<()> {
|
||||
if live_now { println!(" \x1b[2m(run still streaming in background — /logs for what happened while browsing)\x1b[0m"); }
|
||||
}
|
||||
}
|
||||
"/pocs" | "/poc" | "/evidence" | "/artifacts" => {
|
||||
// List the PoC and evidence artifacts a run produced (synthesized
|
||||
// or agent-written), with their paths so they can be retrieved.
|
||||
let h = history.lock().unwrap();
|
||||
let rec = if arg.trim().is_empty() { h.last() } else { pick(&h, arg) };
|
||||
match rec {
|
||||
None => println!(" no run yet — /runs to list, or /pocs <id> after a run"),
|
||||
Some(r) if r.workdir.is_empty() => println!(" run #{} has no workdir on record", r.id),
|
||||
Some(r) => {
|
||||
let dir = std::path::Path::new(&r.workdir);
|
||||
let mut any = false;
|
||||
for (sub, label) in [("pocs", "PoC scripts"), ("evidence", "evidence")] {
|
||||
let p = dir.join(sub);
|
||||
let mut files: Vec<String> = std::fs::read_dir(&p).map(|rd| rd.filter_map(|e| e.ok()).map(|e| e.file_name().to_string_lossy().to_string()).collect()).unwrap_or_default();
|
||||
files.sort();
|
||||
if !files.is_empty() {
|
||||
any = true;
|
||||
println!(" \x1b[1m{label}\x1b[0m ({}):", p.display());
|
||||
for f in files { println!(" {}", p.join(&f).display()); }
|
||||
}
|
||||
}
|
||||
if !any { println!(" no pocs/ or evidence/ files for run #{} ({})", r.id, dir.display()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
"/finding" | "/findings" => {
|
||||
// Build the finding pool: live run if active, else a past run.
|
||||
let pool: Vec<Finding> = match &active {
|
||||
|
||||
Reference in new issue
Block a user