2015-10-08 23:27:04 -04:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
2015-10-13 22:52:55 -04:00
|
|
|
"net/url"
|
2015-10-08 23:27:04 -04:00
|
|
|
)
|
|
|
|
|
2015-10-13 22:52:55 -04:00
|
|
|
// Do a strict referrer check, matching against both the Origin header (if
|
|
|
|
// present) and the Referrer header. If a list of headers is specified, then
|
|
|
|
// Referrer checking will be skipped if any of those headers are present.
|
2015-10-08 23:27:04 -04:00
|
|
|
func strictReferrerCheck(r *http.Request, prefix string, whitelistHeaders []string) bool {
|
2015-10-13 22:52:55 -04:00
|
|
|
p, _ := url.Parse(prefix)
|
|
|
|
|
|
|
|
// if there's an Origin header, check it and skip other checks
|
2015-10-12 04:23:06 -04:00
|
|
|
if origin := r.Header.Get("Origin"); origin != "" {
|
2015-10-13 22:52:55 -04:00
|
|
|
u, _ := url.Parse(origin)
|
|
|
|
return sameOrigin(u, p)
|
2015-10-12 03:28:01 -04:00
|
|
|
}
|
|
|
|
|
2015-10-08 23:27:04 -04:00
|
|
|
for _, header := range whitelistHeaders {
|
|
|
|
if r.Header.Get(header) != "" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-13 22:52:55 -04:00
|
|
|
referrer := r.Header.Get("Referer")
|
|
|
|
u, _ := url.Parse(referrer)
|
|
|
|
return sameOrigin(u, p)
|
|
|
|
}
|
2015-10-08 23:27:04 -04:00
|
|
|
|
2015-10-13 22:52:55 -04:00
|
|
|
// Check if two URLs have the same origin
|
|
|
|
func sameOrigin(u1, u2 *url.URL) bool {
|
|
|
|
// host also contains the port if one was specified
|
|
|
|
return (u1.Scheme == u2.Scheme && u1.Host == u2.Host)
|
2015-10-08 23:27:04 -04:00
|
|
|
}
|