-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
Description
b761e0299e9b+ release.2010-07-01/release For better or worse, the http.Request lets you inject a header via newlines in another header's value. I discovered this because http.Post looks like this: func Post(url string, bodyType string, body io.Reader) (r *Response, err os.Error) ... and I wondered whether or not I could inject my own header via bodyType. Sure enough: package main import ( "http" "os" ) func main() { req := new(http.Request) req.Method = "GET" req.RawURL = "http://example.com/"; url, _ := http.ParseURL(req.RawURL) req.URL = url req.Proto = "HTTP/1.1" req.ProtoMajor = 1 req.ProtoMinor = 1 req.Header = map[string]string { "Foo": "Bar", "Cache-Control": "private", "zzz_HEADER_ATTACK": "foo\r\nCache-Control: public", } req.Host = "example.com" req.UserAgent = "demo/0.1" req.Write(os.Stdout) } $ ./inject GET http://example.com/ HTTP/1.1 Host: example.com User-Agent: demo/0.1 Cache-Control: private Foo: Bar zzz_HEADER_ATTACK: foo Cache-Control: public RFC 2616 says, http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string> And RFC 822 says, for TEXT: text = <any CHAR, including bare ; => atoms, specials, CR & bare LF, but NOT ; comments and including CRLF> ; quoted-strings are ; NOT recognized.