2.8
Pelaporan dan Ekspor
ReportGenerator adalah satu-satunya pintu keluar hasil scan. Satu pemanggilan generate(results, output_path, format) meneruskan pekerjaan ke method privat menurut nilai format, dan nilai di luar daftar memunculkan ValueError(f"Unsupported format: {format}"). core/report_generator.py:25-491
CLI memanggilnya sekali per format. deep_eye.py menyusun daftar format berurutan dari --formats, lalu reporting.formats, lalu reporting.default_format, membuat direktori keluaran, dan memanggil generate untuk setiap entri. deep_eye.py:101-1062 deep_eye.py:371-4283 Semua format berbagi satu nama berkas dasar (deep_eye_<domain>_<timestamp> atau reporting.output_filename), sehingga satu scan menulis beberapa berkas bersaudara di direktori yang sama. deep_eye.py:404-4124
Peta format ke builder
graph TD
R["results dict"] --> G["ReportGenerator.generate"]
G -->|html| H["_generate_html"]
G -->|pdf| P["_generate_pdf"]
G -->|json| J["_generate_json"]
G -->|sarif| S["_generate_sarif"]
G -->|junit| JU["build_junit_xml"]
G -->|csv| C["build_csv"]
G -->|xlsx| X["build_xlsx"]
G -->|lainnya| E["ValueError: Unsupported format"]
style R fill:#336791,color:#fff
style G fill:#f59e0b,color:#000
style H fill:#8b5cf6,color:#fff
style P fill:#8b5cf6,color:#fff
style J fill:#8b5cf6,color:#fff
style S fill:#8b5cf6,color:#fff
style JU fill:#2d7d46,color:#fff
style C fill:#2d7d46,color:#fff
style X fill:#2d7d46,color:#fff
style E fill:#dc2626,color:#fff
%% fig: Dispatch format laporan di ReportGenerator
%% desc: Satu pemanggilan generate memilih generator internal atau builder di utils/exports, dan format tak dikenal berhenti dengan ValueError.Tujuh format didukung. Empat ditulis langsung oleh ReportGenerator, tiga didelegasikan ke builder yang diekspor utils/exports/__init__.py:1-65.
| format | method | ekstensi ext_map | penulis |
|---|---|---|---|
html | _generate_html | html | ReportGenerator |
pdf | _generate_pdf | pdf | ReportGenerator (ReportLab) |
json | _generate_json | json | ReportGenerator |
sarif | _generate_sarif | sarif.json | ReportGenerator |
junit | _generate_junit | junit.xml | build_junit_xml |
csv | _generate_csv | csv | build_csv |
xlsx | _generate_xlsx | xlsx | build_xlsx |
Sumber baris tabel: core/report_generator.py:51-606 core/report_generator.py:62-717 core/report_generator.py:73-868 deep_eye.py:404-4124
HTML dan PDF
_generate_html merender template Jinja2 yang dikembalikan inline oleh _get_html_template. Data yang masuk ke template adalah target, scan_duration, summary, vulnerabilities, severity_counts, urls_scanned, dan reconnaissance. core/report_generator.py:192-2179 Daftar temuan diurutkan _sort_vulnerabilities dengan urutan critical, high, medium, low, info, dan teks ringkasan dibangun _generate_summary dari severity_summary. core/report_generator.py:477-50410
_generate_pdf menyusun dokumen ReportLab: tabel metadata (target, waktu generate, durasi, jumlah URL), tabel severity, ringkasan eksekutif, lalu satu blok per temuan yang memuat URL, parameter, deskripsi, evidence, dan remediation. core/report_generator.py:219-23811 Bila reportlab tidak tersedia atau proses build gagal, ia menulis HTML ke output_path.replace(".pdf", ".html") dan berkas PDF tidak pernah dibuat. core/report_generator.py:464-47512
JSON dan SARIF
_generate_json membersihkan hasil lewat _safe_serialize lebih dulu: dict dipetakan kuncinya, list/tuple/set dijadikan list, dan objek lain menjadi str. Hasil bersih ditulis dengan indent=2 dan ensure_ascii=False. core/report_generator.py:88-11013
_generate_sarif memetakan severity ke level SARIF: critical dan high menjadi error, medium menjadi warning, low dan info menjadi note. Setiap tipe temuan menjadi satu rule dengan id hasil vuln_type.lower() yang spasi dan tanda kurungnya dibuang; satu rule hanya didaftarkan sekali. Dokumen memakai version 2.1.0 dan tool.driver.name Deep Eye versi 1.4.0. core/report_generator.py:112-19014
JUnit, CSV, dan XLSX
build_junit_xml mengembalikan bytes XML. Satu temuan menjadi satu testcase dengan classname berisi tipe temuan dan name berisi URL plus parameter dalam kurung siku. Atribut failures di level testsuites maupun testsuite diisi jumlah temuan, dan isi elemen failure berasal dari _format_failure_body yang menggabungkan payload, evidence (dipotong _EVIDENCE_LIMIT = 500 karakter), remediation, dan cve_references. utils/exports/junit_builder.py:1115 utils/exports/junit_builder.py:39-6716 utils/exports/junit_builder.py:83-11217
build_csv menulis BOM UTF-8 lebih dulu agar Excel membaca encoding dengan benar, lalu header BASE_COLUMNS (11 kolom) dan satu baris per temuan dengan evidence dipotong 1000 karakter serta timestamp berformat UTC. utils/exports/csv_builder.py:11-3218 utils/exports/csv_builder.py:63-8319 Kolom compliance_pci_dss, compliance_soc2, dan compliance_iso_27001 hanya ditambahkan bila ada temuan dengan field compliance; isinya gabungan control_id dengan pemisah "; ". utils/exports/csv_builder.py:37-41 utils/exports/csv_builder.py:52-56 utils/exports/csv_builder.py:101-105
build_xlsx mengembalikan True saat workbook tersimpan dan False saat openpyxl tidak ada atau penyimpanan gagal. Workbook dibuat dari nol, sheet default dibuang, lalu sheet diisi berurutan; sheet Control Summary hanya dibuat bila ada temuan dengan data compliance. utils/exports/xlsx_builder.py:282-33023
| sheet | fungsi | isi |
|---|---|---|
Summary | _build_summary_sheet | target, waktu generate, durasi, urls_crawled, total temuan, hitungan per severity |
Vulnerabilities | _build_vulns_sheet | header VULN_COLUMNS, freeze A2, autofilter |
Reconnaissance | _build_recon_sheet | baris DNS, OSINT (emails, subdomains, github_leaks, breaches), dan technologies |
CVEs | _build_cves_sheet | pivot cve_references per temuan, header CVE_HEADERS |
Compliance | _build_compliance_sheet | satu baris per control dengan status failing |
Control Summary | _build_control_summary_sheet | hitungan temuan per (framework, control_id) dan severity tertinggi |
Sumber baris tabel: utils/exports/xlsx_builder.py:84-10524 utils/exports/xlsx_builder.py:108-14325 utils/exports/xlsx_builder.py:146-185 utils/exports/xlsx_builder.py:188-211 utils/exports/xlsx_builder.py:214-238 utils/exports/xlsx_builder.py:241-279
Tiap baris temuan di sheet Vulnerabilities diberi warna latar dan font dari SEVERITY_COLORS. utils/exports/xlsx_builder.py:11-1730 utils/exports/xlsx_builder.py:108-14325
Pelabelan compliance PCI-DSS, SOC 2, dan ISO 27001
graph LR
V["self.vulnerabilities"] --> EN["enrich_vulnerabilities"]
EN --> MV["map_vuln"]
MV --> LF["load_frameworks"]
LF --> FW["pci_dss_v4.json / soc2_cc.json / iso_27001_2022.json"]
EN --> CF["field compliance pada tiap vuln"]
CF --> CC["COMPLIANCE_COLUMNS di build_csv"]
CF --> CS["_build_compliance_sheet"]
CS --> CTRL["_build_control_summary_sheet"]
style V fill:#336791,color:#fff
style FW fill:#336791,color:#fff
style EN fill:#f59e0b,color:#000
style MV fill:#f59e0b,color:#000
style LF fill:#f59e0b,color:#000
style CF fill:#8b5cf6,color:#fff
style CC fill:#2d7d46,color:#fff
style CS fill:#2d7d46,color:#fff
style CTRL fill:#8b5cf6,color:#fff
%% fig: Alur pelabelan compliance sampai ke CSV dan XLSX
%% desc: Enrichment menambah field compliance pada tiap temuan, lalu kolom CSV dan sheet Excel membaca field yang sama.FRAMEWORK_KEYS memetakan kunci config pci_dss, soc2, dan iso_27001 ke nama berkas JSON serta nama tampilan PCI-DSS, SOC 2, dan ISO 27001. utils/compliance/mapper.py:12-1631 load_frameworks membaca berkas di direktori frameworks; kunci tak dikenal memunculkan logger.warning(f"Unknown compliance framework key: {key}") dan berkas yang hilang memunculkan logger.warning(f"Framework file missing: {path}"), keduanya tanpa menghentikan proses. utils/compliance/mapper.py:21-5832
map_vuln mencari vuln_mappings untuk tipe temuan dan melengkapinya dengan title serta category dari controls. Tipe yang tidak dikenal menghasilkan list kosong. utils/compliance/mapper.py:61-8933 enrich_vulnerabilities menulis hasilnya ke field compliance tiap temuan secara in-place. utils/compliance/mapper.py:92-10334
Enrichment dipicu engine hanya bila compliance.enabled bernilai true, dengan default frameworks ['pci_dss', 'soc2', 'iso_27001'], dan kegagalannya hanya dicatat sebagai error. core/scanner_engine.py:912-92435 Karena field compliance sudah menempel pada temuan, build_csv dan build_xlsx tidak perlu memanggil mapper sendiri.
Notifikasi hasil scan
sequenceDiagram
participant E as ScannerEngine
participant N as NotificationManager
participant S as _sanitize_evidence
participant W as Slack / Discord / SMTP
E->>N: send_critical_vulnerability(vuln, target_url)
N->>N: cek enabled dan notify_on_critical
N->>S: evidence
S-->>N: evidence dengan token disamarkan
N->>W: webhook atau SMTP
W-->>N: status kirim
E->>N: send_scan_complete(results)
N->>W: ringkasan severity per kanal aktif
%% fig: Pengiriman notifikasi setelah dan selama scan
%% desc: Engine memicu notifikasi per temuan critical dan sekali di akhir scan, semuanya lewat NotificationManager yang menyamarkan evidence.NotificationManager membaca blok notifications dan tidak mengirim apa pun selama enabled masih False (default). send_scan_complete mencoba kanal email, slack, dan discord yang aktif, lalu mengembalikan True bila sedikitnya satu kanal berhasil. utils/notification_manager.py:20-3236 utils/notification_manager.py:34-6537 Isi pesannya diringkas _prepare_notification_data menjadi target, durasi, urls_crawled, total temuan, dan hitungan per severity. utils/notification_manager.py:135-15338
Evidence yang dikirim ke kanal eksternal melewati _sanitize_evidence: pola bearer, token, session_id, api_key, password, secret, authorization, set-cookie, cookie, dan string base64 panjang diganti **REDACTED**, lalu dipotong 500 karakter. utils/notification_manager.py:67-9439 _send_email berhenti dengan logger.warning("Email configuration incomplete") bila salah satu dari smtp_server, username, password, from_address, atau to_addresses kosong. utils/notification_manager.py:155-16940 _send_slack berhenti dengan logger.warning("Slack webhook URL not configured") bila slack.webhook_url kosong. utils/notification_manager.py:195-20341
Temuan ber-severity critical memicu send_critical_vulnerability segera setelah temuan ditambahkan ke state, dan exception di jalur ini hanya dicatat di level debug. core/scanner_engine.py:601-60642 utils/notification_manager.py:96-13343 Satu notifikasi ringkasan dikirim setelah durasi scan dihitung dan fase berpindah ke REPORTING. core/scanner_engine.py:955-95944
Jebakan dan batasan
⚠️
_generate_pdfmenangkapImportErrormaupun exception lain, lalu diam-diam menulis HTML keoutput_path.replace(".pdf", ".html"). Path
⚠️
build_junit_xmlmengisifailuresdengan jumlah temuan, sehingga setiap temuan dianggap test gagal. CI yang menolak build saat ada failure akan selalu gagal pada scan yang menemukan minimal satu temuan. utils/exports/junit_builder.py:39-6716
⚠️
build_xlsxmemanggil_ensure_openpyxl, yang dapat menjalankanpip install openpyxlsecara interaktif ketikaopenpyxlbelum ada dan stdin berupa tty. Matikan lewatreporting.xlsx_interactive_install: false; bila tidak interaktif, fungsi hanya mengembalikanFalsedan tidak ada berkas yang ditulis. utils/exports/xlsx_builder.py:46-7345 core/report_generator.py:73-868
Versi yang dicetak berbeda antar format: dokumen SARIF menyebut 1.4.0, sedangkan footer template HTML menyebut Deep Eye v1.3.0. core/report_generator.py:112-19014 core/report_generator.py:1012-101546
Untuk urutan fase scan yang memicu pelaporan, lihat Alur Scan. Untuk asal field cve_references yang muncul di JUnit, CSV, dan sheet CVEs, lihat CVE Intelligence dan RAG. Untuk perbandingan dua hasil scan, lihat Scan Diff dan Retest. Untuk pemilihan format dari command line, lihat Antarmuka CLI.