44 "fmt"
55 "net"
66 "net/http"
7- "strconv"
87 "strings"
98 "time"
109
@@ -23,6 +22,10 @@ const (
2322 combinedLogFormat = commonLogFormat + ` "%s" "%s"`
2423 // We add the duration in ms, a requested host and a flow id and audit log
2524 accessLogFormat = combinedLogFormat + " %d %s %s %s\n "
25+
26+ // KeyMaskedQueryParams represents the key used to store and retrieve masked query parameters
27+ // from the additional data.
28+ KeyMaskedQueryParams = "maskedQueryParams"
2629)
2730
2831type accessLogFormatter struct {
@@ -111,13 +114,32 @@ func stripQueryString(u string) string {
111114 }
112115}
113116
117+ // maskQueryParams masks (i.e., hashing) specific query parameters in the provided request's URI.
118+ // Returns the obfuscated URI.
119+ func maskQueryParams (req * http.Request , maskedQueryParams []string ) string {
120+ strippedURI := stripQueryString (req .RequestURI )
121+
122+ params := req .URL .Query ()
123+ for i := range maskedQueryParams {
124+ val := params .Get (maskedQueryParams [i ])
125+ if val == "" {
126+ continue
127+ }
128+
129+ hashed := hash (val )
130+ params .Set (maskedQueryParams [i ], fmt .Sprintf ("%d" , hashed ))
131+ }
132+
133+ return fmt .Sprintf ("%s?%s" , strippedURI , params .Encode ())
134+ }
135+
114136func hash (val string ) uint64 {
115137 return xxhash .Sum64String (val )
116138}
117139
118140// Logs an access event in Apache combined log format (with a minor customization with the duration).
119141// Additional allows to provide extra data that may be also logged, depending on the specific log format.
120- func LogAccess (entry * AccessEntry , additional map [string ]interface {}, maskedQueryParams [] string ) {
142+ func LogAccess (entry * AccessEntry , additional map [string ]interface {}) {
121143 if accessLog == nil || entry == nil {
122144 return
123145 }
@@ -150,21 +172,10 @@ func LogAccess(entry *AccessEntry, additional map[string]interface{}, maskedQuer
150172 uri = entry .Request .RequestURI
151173 if stripQuery {
152174 uri = stripQueryString (uri )
153- } else if len (maskedQueryParams ) != 0 {
154- strippedURI := stripQueryString (uri )
155-
156- params := entry .Request .URL .Query ()
157- for i := range maskedQueryParams {
158- val := params .Get (maskedQueryParams [i ])
159- if val == "" {
160- continue
161- }
162-
163- hashed := hash (val )
164- params .Set (maskedQueryParams [i ], strconv .Itoa (int (hashed )))
175+ } else if keys , ok := additional [KeyMaskedQueryParams ].([]string ); ok {
176+ if len (keys ) > 0 {
177+ uri = maskQueryParams (entry .Request , keys )
165178 }
166-
167- uri = fmt .Sprintf ("%s?%s" , strippedURI , params .Encode ())
168179 }
169180
170181 auditHeader = entry .Request .Header .Get (logFilter .UnverifiedAuditHeader )
@@ -187,6 +198,7 @@ func LogAccess(entry *AccessEntry, additional map[string]interface{}, maskedQuer
187198 "auth-user" : authUser ,
188199 }
189200
201+ delete (additional , KeyMaskedQueryParams )
190202 for k , v := range additional {
191203 logData [k ] = v
192204 }
0 commit comments