Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update backend/utils/pdf_generator.py
Browse files- backend/utils/pdf_generator.py +39 -45
backend/utils/pdf_generator.py
CHANGED
|
@@ -970,54 +970,48 @@ def generate_scan_pdf(scan, vulnerabilities):
|
|
| 970 |
elements.append(Paragraph(rem_final_text, normal))
|
| 971 |
elements.append(Spacer(1, 25))
|
| 972 |
|
| 973 |
-
# --- APPENDIX: REQUIRES MANUAL VERIFICATION
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
|
| 977 |
-
|
| 978 |
-
|
| 979 |
|
| 980 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 981 |
|
| 982 |
-
|
| 983 |
-
elements.append(Paragraph("<b>A.1 Blind XSS Payloads Submitted to 1 Form(s) — Awaiting Callback [Requires Verification]</b>", styles['Heading3']))
|
| 984 |
-
a1_data = [
|
| 985 |
-
["Status", Paragraph("<font color='#EA580C'>Requires Verification</font>", normal), "CVSS Score", "8.2"],
|
| 986 |
-
["Category", "Blind XSS", "Severity", Paragraph("<font color='#99CC33'>Low</font>", normal)],
|
| 987 |
-
["CVSS Vector", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", "", ""]
|
| 988 |
-
]
|
| 989 |
-
a1_table = Table(a1_data, colWidths=[80, 150, 80, 150])
|
| 990 |
-
a1_table.setStyle(TableStyle([
|
| 991 |
-
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#F9FAFB")),
|
| 992 |
-
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor("#E5E7EB")),
|
| 993 |
-
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
|
| 994 |
-
('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'),
|
| 995 |
-
]))
|
| 996 |
-
elements.append(a1_table)
|
| 997 |
-
elements.append(Spacer(1, 8))
|
| 998 |
-
a1_desc = f"<b>Description:</b><br/>Out-of-band XSS payloads were submitted to 1 form endpoint(s).<br/>Callback listener configured at: <font name='Courier'>https://xss-reporting.internal/callback</font><br/>• {html.escape(target_url)} (injection attempted)<br/><br/><i>This is NOT a confirmed finding. Blind XSS requires an external callback to verify execution. Monitor your XSS hunter / callback server for incoming requests from https://xss-reporting.internal/callback. If a callback is received, escalate to Critical.</i>"
|
| 999 |
-
elements.append(Paragraph(a1_desc, normal))
|
| 1000 |
-
elements.append(Spacer(1, 15))
|
| 1001 |
|
| 1002 |
-
|
| 1003 |
-
|
| 1004 |
-
|
| 1005 |
-
|
| 1006 |
-
|
| 1007 |
-
|
| 1008 |
-
|
| 1009 |
-
|
| 1010 |
-
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
|
| 1014 |
-
|
| 1015 |
-
|
| 1016 |
-
|
| 1017 |
-
|
| 1018 |
-
|
| 1019 |
-
|
| 1020 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1021 |
|
| 1022 |
# Legal Disclaimer & Confidentiality Notice
|
| 1023 |
elements.append(PageBreak())
|
|
|
|
| 970 |
elements.append(Paragraph(rem_final_text, normal))
|
| 971 |
elements.append(Spacer(1, 25))
|
| 972 |
|
| 973 |
+
# --- APPENDIX: REQUIRES MANUAL VERIFICATION (ONLY IF UNCONFIRMED FINDINGS EXIST) ---
|
| 974 |
+
unconfirmed_findings = [
|
| 975 |
+
v for v in (findings or [])
|
| 976 |
+
if getattr(v, 'requires_verification', False)
|
| 977 |
+
or (getattr(v, 'confidence', '') and str(getattr(v, 'confidence', '')).lower() in ['unconfirmed', 'requires verification', 'heuristic'])
|
| 978 |
+
]
|
| 979 |
|
| 980 |
+
if unconfirmed_findings:
|
| 981 |
+
elements.append(PageBreak())
|
| 982 |
+
elements.append(Paragraph("<b>Appendix: Requires Manual Verification</b>", heading2))
|
| 983 |
+
elements.append(Spacer(1, 5))
|
| 984 |
+
elements.append(Paragraph("The following findings were flagged by automated heuristic signatures or out-of-band probes, but lack full payload confirmation. They are excluded from executive summary severity counts and require manual verification by a security engineer.", normal))
|
| 985 |
+
elements.append(Spacer(1, 15))
|
| 986 |
|
| 987 |
+
target_url = scan.target_url if (scan and getattr(scan, 'target_url', None)) else 'https://www.target.com'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 988 |
|
| 989 |
+
for u_idx, u_vuln in enumerate(unconfirmed_findings, start=1):
|
| 990 |
+
u_title = getattr(u_vuln, 'title', f"Unconfirmed Finding #{u_idx}")
|
| 991 |
+
u_cvss = str(getattr(u_vuln, 'cvss_score', '0.0'))
|
| 992 |
+
u_cat = getattr(u_vuln, 'category', 'General')
|
| 993 |
+
u_sev = getattr(u_vuln, 'severity', 'Low')
|
| 994 |
+
u_desc = getattr(u_vuln, 'description', '')
|
| 995 |
+
u_vec = getattr(u_vuln, 'cvss_vector', 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N')
|
| 996 |
+
|
| 997 |
+
elements.append(Paragraph(f"<b>A.{u_idx} {html.escape(u_title)} [Requires Verification]</b>", styles['Heading3']))
|
| 998 |
+
u_data = [
|
| 999 |
+
["Status", Paragraph("<font color='#EA580C'>Requires Verification</font>", normal), "CVSS Score", u_cvss],
|
| 1000 |
+
["Category", u_cat, "Severity", Paragraph(f"<font color='#99CC33'>{u_sev}</font>", normal)],
|
| 1001 |
+
["CVSS Vector", u_vec, "", ""]
|
| 1002 |
+
]
|
| 1003 |
+
u_table = Table(u_data, colWidths=[80, 150, 80, 150])
|
| 1004 |
+
u_table.setStyle(TableStyle([
|
| 1005 |
+
('BACKGROUND', (0,0), (-1,-1), colors.HexColor("#F9FAFB")),
|
| 1006 |
+
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor("#E5E7EB")),
|
| 1007 |
+
('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'),
|
| 1008 |
+
('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'),
|
| 1009 |
+
]))
|
| 1010 |
+
elements.append(u_table)
|
| 1011 |
+
elements.append(Spacer(1, 8))
|
| 1012 |
+
desc_p = f"<b>Description:</b><br/>{html.escape(u_desc)}"
|
| 1013 |
+
elements.append(Paragraph(desc_p, normal))
|
| 1014 |
+
elements.append(Spacer(1, 15))
|
| 1015 |
|
| 1016 |
# Legal Disclaimer & Confidentiality Notice
|
| 1017 |
elements.append(PageBreak())
|