● Notice //GitHub (@shehzade) is temporarily suspended pending an automated false-positive review. All tools are hosted on this Code Mirror and available on request (contact); GitHub links will return once reinstated.
PUBLIC MIRRORGo v1.0

Multi-protocol network egress assessment and DLP verification framework featuring automated L4 sweeps, corporate proxy traversal, and covert protocol smuggling across 20+ channels.

$ git clone https://shehzade.io/repos/contraband.git Copy
Source ZIP (1.93 MB)
Code 174 Commits 1
contraband / pkg / report / html.go
← Back to directory
115 lines · 3.2 KB
Raw
1package report
2
3import (
4 "fmt"
5 "html/template"
6 "io"
7 "math"
8 "strings"
9 "time"
10
11 "github.com/shehzade/contraband/pkg/common"
12 "github.com/shehzade/contraband/pkg/report/templates"
13)
14
15// HTMLTemplateFuncs provides custom helper functions for formatting dashboard components.
16var HTMLTemplateFuncs = template.FuncMap{
17 "formatMS": func(v interface{}) string {
18 switch val := v.(type) {
19 case float64:
20 return fmt.Sprintf("%.2fms", val)
21 case float32:
22 return fmt.Sprintf("%.2fms", float64(val))
23 case int:
24 return fmt.Sprintf("%.2fms", float64(val))
25 case int64:
26 return fmt.Sprintf("%.2fms", float64(val))
27 case time.Duration:
28 return fmt.Sprintf("%.2fms", float64(val.Microseconds())/1000.0)
29 default:
30 return fmt.Sprintf("%vms", val)
31 }
32 },
33 "divDurMS": func(d time.Duration) float64 {
34 return float64(d.Microseconds()) / 1000.0
35 },
36 "formatBytes": func(b int64) string {
37 return common.FormatBytes(b)
38 },
39 "formatRFC3339MS": func(t time.Time) string {
40 return t.UTC().Format("2006-01-02 15:04:05.000")
41 },
42 "verdictClass": func(v common.Verdict) string {
43 switch v {
44 case common.VerdictSuccess:
45 return "verdict-success"
46 case common.VerdictBlockedL4:
47 return "verdict-blocked-l4"
48 case common.VerdictBlockedL7:
49 return "verdict-blocked-l7"
50 case common.VerdictBlockedDLP:
51 return "verdict-blocked-dlp"
52 default:
53 return "verdict-unknown"
54 }
55 },
56 "verdictBadge": func(v common.Verdict) template.HTML {
57 switch v {
58 case common.VerdictSuccess:
59 return template.HTML(`<span class="badge badge-success">EXFIL_SUCCESS</span>`)
60 case common.VerdictBlockedL4:
61 return template.HTML(`<span class="badge badge-blocked-l4">BLOCKED_L4</span>`)
62 case common.VerdictBlockedL7:
63 return template.HTML(`<span class="badge badge-blocked-l7">BLOCKED_L7</span>`)
64 case common.VerdictBlockedDLP:
65 return template.HTML(`<span class="badge badge-blocked-dlp">BLOCKED_DLP</span>`)
66 default:
67 return template.HTML(`<span class="badge badge-unknown">UNKNOWN</span>`)
68 }
69 },
70 "calcGaugeOffset": func(score float64) float64 {
71 // Semi-circle arc length: pi * 100 = 314.16
72 const arcLength = 314.159
73 if score < 0 {
74 score = 0
75 }
76 if score > 100 {
77 score = 100
78 }
79 return arcLength * (1.0 - (score / 100.0))
80 },
81 "calcNeedleAngle": func(score float64) int {
82 // Needle rotation angle: 180 degrees at 0%, 270 degrees at 50%, 360 degrees at 100%
83 if score < 0 {
84 score = 0
85 }
86 if score > 100 {
87 score = 100
88 }
89 return int(math.Round(180.0 + (score * 1.8)))
90 },
91 "truncateHash": func(h string, maxLen int) string {
92 if len(h) <= maxLen {
93 return h
94 }
95 return h[:maxLen] + "…"
96 },
97}
98
99// GenerateHTML renders the assessment report into a standalone interactive HTML string.
100func GenerateHTML(report *AssessmentReport) (string, error) {
101 var sb strings.Builder
102 if err := WriteHTML(&sb, report); err != nil {
103 return "", err
104 }
105 return sb.String(), nil
106}
107
108// WriteHTML streams rendered HTML into the provided io.Writer for memory efficiency.
109func WriteHTML(w io.Writer, report *AssessmentReport) error {
110 tmpl, err := template.New("dashboard").Funcs(HTMLTemplateFuncs).Parse(templates.DashboardHTML)
111 if err != nil {
112 return fmt.Errorf("failed to parse dashboard HTML template: %w", err)
113 }
114 return tmpl.Execute(w, report)
115}