c461faa2fb
Complete pentest feature overhaul: SSE streaming, session-persistent browser tool (CDP), AES-256 credential encryption, auto-screenshots in reports, code-level remediation correlation, SAST triage chunking, context window optimization, test user cleanup (Keycloak/Auth0/Okta), wizard dropdowns, attack chain improvements, architecture docs with Mermaid diagrams. Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com> Reviewed-on: #16
70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
mod archive;
|
|
mod html;
|
|
mod pdf;
|
|
|
|
use compliance_core::models::dast::DastFinding;
|
|
use compliance_core::models::finding::Finding;
|
|
use compliance_core::models::pentest::{
|
|
AttackChainNode, CodeContextHint, PentestConfig, PentestSession,
|
|
};
|
|
use compliance_core::models::sbom::SbomEntry;
|
|
use sha2::{Digest, Sha256};
|
|
|
|
/// Report archive with metadata
|
|
pub struct ReportArchive {
|
|
/// The password-protected ZIP bytes
|
|
pub archive: Vec<u8>,
|
|
/// SHA-256 hex digest of the archive
|
|
pub sha256: String,
|
|
}
|
|
|
|
/// Report context gathered from the database
|
|
pub struct ReportContext {
|
|
pub session: PentestSession,
|
|
pub target_name: String,
|
|
pub target_url: String,
|
|
pub findings: Vec<DastFinding>,
|
|
pub attack_chain: Vec<AttackChainNode>,
|
|
pub requester_name: String,
|
|
pub requester_email: String,
|
|
pub config: Option<PentestConfig>,
|
|
/// SAST findings for the linked repository (for code-level correlation)
|
|
pub sast_findings: Vec<Finding>,
|
|
/// Vulnerable dependencies from SBOM
|
|
pub sbom_entries: Vec<SbomEntry>,
|
|
/// Code knowledge graph entry points linked to SAST findings
|
|
pub code_context: Vec<CodeContextHint>,
|
|
}
|
|
|
|
/// Generate a password-protected ZIP archive containing the pentest report.
|
|
///
|
|
/// The archive contains:
|
|
/// - `report.pdf` — Professional pentest report (PDF)
|
|
/// - `report.html` — HTML source (fallback)
|
|
/// - `findings.json` — Raw findings data
|
|
/// - `attack-chain.json` — Attack chain timeline
|
|
///
|
|
/// Files are encrypted with AES-256 inside the ZIP (standard WinZip AES format,
|
|
/// supported by 7-Zip, WinRAR, macOS Archive Utility, etc.).
|
|
pub async fn generate_encrypted_report(
|
|
ctx: &ReportContext,
|
|
password: &str,
|
|
) -> Result<ReportArchive, String> {
|
|
let html = html::build_html_report(ctx);
|
|
|
|
// Convert HTML to PDF via headless Chrome
|
|
let pdf_bytes = pdf::html_to_pdf(&html).await?;
|
|
|
|
let zip_bytes = archive::build_zip(ctx, password, &html, &pdf_bytes)
|
|
.map_err(|e| format!("Failed to create archive: {e}"))?;
|
|
|
|
let mut hasher = Sha256::new();
|
|
hasher.update(&zip_bytes);
|
|
let sha256 = hex::encode(hasher.finalize());
|
|
|
|
Ok(ReportArchive {
|
|
archive: zip_bytes,
|
|
sha256,
|
|
})
|
|
}
|