-
Notifications
You must be signed in to change notification settings - Fork 26
/
main.go
151 lines (122 loc) · 4.91 KB
/
main.go
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"flag"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"github.com/jacobbednarz/go-csp-collector/internal/handler"
"github.com/jacobbednarz/go-csp-collector/internal/utils"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
)
const (
// Default health check url.
defaultHealthCheckPath = "/_healthcheck"
)
var (
// Rev is set at build time and holds the revision that the package
// was created at.
Rev = "dev"
// Shared defaults for the logger output. This ensures that we are
// using the same keys for the `FieldKey` values across both formatters.
logFieldMapDefaults = log.FieldMap{
log.FieldKeyTime: "timestamp",
log.FieldKeyLevel: "level",
log.FieldKeyMsg: "message",
}
)
var logger = logrus.New()
func init() {
logger.SetOutput(os.Stdout)
logger.SetLevel(log.InfoLevel)
}
func main() {
version := flag.Bool("version", false, "Display the version")
debugFlag := flag.Bool("debug", false, "Output additional logging for debugging")
outputFormat := flag.String("output-format", "text", "Define how the violation reports are formatted for output.\nDefaults to 'text'. Valid options are 'text' or 'json'")
blockedURIFile := flag.String("filter-file", "", "Blocked URI Filter file")
listenPort := flag.Int("port", 8080, "Port to listen on")
healthCheckPath := flag.String("health-check-path", defaultHealthCheckPath, "Health checker path")
truncateQueryStringFragment := flag.Bool("truncate-query-fragment", false, "Truncate query string and fragment from document-uri, referrer and blocked-uri before logging (to reduce chances of accidentally logging sensitive data)")
logClientIP := flag.Bool("log-client-ip", false, "Log the reporting client IP address")
logTruncatedClientIP := flag.Bool("log-truncated-client-ip", false, "Log the truncated client IP address (IPv4: /24, IPv6: /64")
metadataObject := flag.Bool("query-params-metadata", false, "Write query parameters of the report URI as JSON object under metadata instead of the single metadata string")
flag.Parse()
if *version {
fmt.Printf("csp-collector (%s)\n", Rev)
os.Exit(0)
}
if *debugFlag {
logger.SetLevel(log.DebugLevel)
}
if *outputFormat == "json" {
logger.SetFormatter(&log.JSONFormatter{
FieldMap: logFieldMapDefaults,
})
} else {
logger.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
DisableLevelTruncation: true,
QuoteEmptyFields: true,
DisableColors: true,
FieldMap: logFieldMapDefaults,
})
}
logger.Debug("starting up...")
ignoredBlockedURIs := utils.DefaultIgnoredBlockedURIs
if *blockedURIFile != "" {
logger.Debugf("using Filter list from file at: %s\n", *blockedURIFile)
content, err := os.ReadFile(*blockedURIFile)
if err != nil {
log.Fatalf("error reading Blocked File list: %s", *blockedURIFile)
}
ignoredBlockedURIs = utils.TrimEmptyAndComments(strings.Split(string(content), "\n"))
} else {
logger.Debug("using filter list from internal list")
}
r := mux.NewRouter()
r.HandleFunc(*healthCheckPath, handler.HealthcheckHandler).Methods("GET")
r.Handle("/csp/report-only", &handler.CSPViolationReportHandler{
BlockedURIs: ignoredBlockedURIs,
TruncateQueryStringFragment: *truncateQueryStringFragment,
LogClientIP: *logClientIP,
LogTruncatedClientIP: *logTruncatedClientIP,
MetadataObject: *metadataObject,
Logger: logger,
ReportOnly: true,
}).Methods("POST")
r.Handle("/csp", &handler.CSPViolationReportHandler{
BlockedURIs: ignoredBlockedURIs,
TruncateQueryStringFragment: *truncateQueryStringFragment,
LogClientIP: *logClientIP,
LogTruncatedClientIP: *logTruncatedClientIP,
MetadataObject: *metadataObject,
Logger: logger,
ReportOnly: false,
}).Methods("POST")
r.HandleFunc("/reporting-api/csp", handler.ReportAPICorsHandler).Methods("OPTIONS")
r.Handle("/reporting-api/csp", &handler.ReportAPIViolationReportHandler{
BlockedURIs: ignoredBlockedURIs,
TruncateQueryStringFragment: *truncateQueryStringFragment,
LogClientIP: *logClientIP,
LogTruncatedClientIP: *logTruncatedClientIP,
MetadataObject: *metadataObject,
Logger: logger,
}).Methods("POST")
r.Handle("/", &handler.CSPViolationReportHandler{
BlockedURIs: ignoredBlockedURIs,
TruncateQueryStringFragment: *truncateQueryStringFragment,
LogClientIP: *logClientIP,
LogTruncatedClientIP: *logTruncatedClientIP,
MetadataObject: *metadataObject,
Logger: logger,
ReportOnly: false,
}).Methods("POST")
r.NotFoundHandler = r.NewRoute().HandlerFunc(http.NotFound).GetHandler()
logger.Debugf("blocked URI list: %s", ignoredBlockedURIs)
logger.Debugf("listening on TCP port: %s", strconv.Itoa(*listenPort))
logger.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", strconv.Itoa(*listenPort)), r))
}