1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package collector
import (
"log"
"net/http"
"strconv"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"bnbl.io/csp_exporter/csp"
)
type Collector interface {
Collect(app string, report *csp.Report)
Handler() http.Handler
}
type collector struct {
reportCounter *prometheus.CounterVec
}
const (
labelApp = "app"
labelBlockedURI = "blocked_uri"
labelDisposition = "disposition"
labelDocumentURI = "document_uri"
labelEffectiveDirective = "effective_directive"
labelOriginalPolicy = "original_policy"
labelReferrer = "referrer"
labelScriptSample = "script_sample"
labelStatusCode = "status_code"
labelViolatedDirective = "violated_directive"
labelSourceFile = "source_file"
labelLineNumber = "line_number"
labelColumnNumber = "column_number"
)
func NewCollector() (Collector, error) {
c := &collector{
reportCounter: prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: "http",
Subsystem: "csp",
Name: "violations_count",
Help: "Count of CSP violation reports.",
}, []string{
labelApp,
labelBlockedURI,
labelDisposition,
labelDocumentURI,
labelEffectiveDirective,
labelOriginalPolicy,
labelReferrer,
labelScriptSample,
labelStatusCode,
labelViolatedDirective,
labelSourceFile,
labelLineNumber,
labelColumnNumber,
}),
}
if err := prometheus.Register(c.reportCounter); err != nil {
log.Fatalf("could not register report counter with prometheus: %v", err)
}
return c, nil
}
func (c *collector) Collect(app string, report *csp.Report) {
labels := prometheus.Labels{
labelApp: app,
labelBlockedURI: report.BlockedURI,
labelDisposition: report.Disposition,
labelDocumentURI: report.DocumentURI,
labelEffectiveDirective: report.EffectiveDirective,
labelOriginalPolicy: report.OriginalPolicy,
labelReferrer: report.Referrer,
labelScriptSample: report.ScriptSample,
labelViolatedDirective: report.ViolatedDirective,
labelSourceFile: report.SourceFile,
labelStatusCode: "",
labelLineNumber: "",
labelColumnNumber: "",
}
if report.StatusCode > 0 {
labels[labelStatusCode] = strconv.Itoa(report.StatusCode)
}
if report.LineNumber > 0 {
labels[labelLineNumber] = strconv.Itoa(report.LineNumber)
}
if report.ColumnNumber > 0 {
labels[labelColumnNumber] = strconv.Itoa(report.ColumnNumber)
}
c.reportCounter.With(labels).Inc()
}
func (c *collector) Handler() http.Handler {
return promhttp.Handler()
}
|