@@ -16,6 +16,11 @@ import (
1616var _ io.ReadCloser = (* wrapper )(nil )
1717var _ http.ResponseWriter = (* wrapper )(nil )
1818
19+ // stripCRLF removes CR/LF to prevent log injection (CWE-117).
20+ func stripCRLF (s string ) string {
21+ return strings .ReplaceAll (strings .ReplaceAll (s , "\n " , "" ), "\r " , "" )
22+ }
23+
1924type wrapper struct {
2025 io.ReadCloser
2126 read int
@@ -27,7 +32,6 @@ type wrapper struct {
2732
2833 w http.ResponseWriter
2934 code int
30- data []byte
3135}
3236
3337func (w * wrapper ) Read (b []byte ) (int , error ) {
@@ -85,7 +89,6 @@ func (w *wrapper) reset() {
8589 w .wc = false
8690 w .write = 0
8791 w .w = nil
88- w .data = nil
8992 w .ReadCloser = nil
9093}
9194
@@ -128,8 +131,7 @@ func (l *lm) Log(next http.Handler, accessLogs bool) http.Handler {
128131}
129132
130133func (l * lm ) writeLog (accessLog bool , r * http.Request , bw * wrapper , start time.Time ) {
131- switch accessLog {
132- case false :
134+ if ! accessLog {
133135 l .log .Info ("http log" ,
134136 "status" , bw .code ,
135137 "method" , r .Method ,
@@ -140,38 +142,31 @@ func (l *lm) writeLog(accessLog bool, r *http.Request, bw *wrapper, start time.T
140142 "write_bytes" , bw .write ,
141143 "start" , start ,
142144 "elapsed" , time .Since (start ).Milliseconds ())
143- case true :
144- // external/cwe/cwe-117
145- usrA := r .UserAgent ()
146- usrA = strings .ReplaceAll (usrA , "\n " , "" )
147- usrA = strings .ReplaceAll (usrA , "\r " , "" )
148-
149- rfr := r .Referer ()
150- rfr = strings .ReplaceAll (rfr , "\n " , "" )
151- rfr = strings .ReplaceAll (rfr , "\r " , "" )
152-
153- rq := r .URL .RawQuery
154- rq = strings .ReplaceAll (rq , "\n " , "" )
155- rq = strings .ReplaceAll (rq , "\r " , "" )
156-
157- l .log .Info ("http access log" ,
158- "read_bytes" , bw .read ,
159- "write_bytes" , bw .write ,
160- "status" , bw .code ,
161- "method" , r .Method ,
162- "URI" , r .RequestURI ,
163- "URL" , r .URL .String (),
164- "remote_address" , r .RemoteAddr ,
165- "query" , rq ,
166- "content_len" , r .ContentLength ,
167- "host" , r .Host ,
168- "user_agent" , usrA ,
169- "referer" , rfr ,
170- "time_local" , time .Now ().Format ("02/Jan/06:15:04:05 -0700" ),
171- "request_time" , time .Now (),
172- "start" , start ,
173- "elapsed" , time .Since (start ).Milliseconds ())
145+ return
174146 }
147+
148+ // external/cwe/cwe-117
149+ usrA := stripCRLF (r .UserAgent ())
150+ rfr := stripCRLF (r .Referer ())
151+ rq := stripCRLF (r .URL .RawQuery )
152+
153+ l .log .Info ("http access log" ,
154+ "read_bytes" , bw .read ,
155+ "write_bytes" , bw .write ,
156+ "status" , bw .code ,
157+ "method" , r .Method ,
158+ "URI" , r .RequestURI ,
159+ "URL" , r .URL .String (),
160+ "remote_address" , r .RemoteAddr ,
161+ "query" , rq ,
162+ "content_len" , r .ContentLength ,
163+ "host" , r .Host ,
164+ "user_agent" , usrA ,
165+ "referer" , rfr ,
166+ "time_local" , start .Format ("02/Jan/06:15:04:05 -0700" ),
167+ "request_time" , start ,
168+ "start" , start ,
169+ "elapsed" , time .Since (start ).Milliseconds ())
175170}
176171
177172func (l * lm ) getW (w http.ResponseWriter ) * wrapper {
0 commit comments