Download this file
| 1 | package todo |
| 2 | |
| 3 | import "net/http" |
| 4 | |
| 5 | // originCheck is the contract's cross-site protection: a POST carrying |
| 6 | // an Origin header that isn't exactly this app's own answers 403, and a |
| 7 | // POST with no Origin header is allowed. |
| 8 | // |
| 9 | // It is deliberately not csrf.Protect. Protect refuses a POST that |
| 10 | // carries none of Sec-Fetch-Site, Origin and Referer, which the |
| 11 | // bakeoff's shared tests and load tests send and the contract allows; |
| 12 | // and it trusts Sec-Fetch-Site ahead of Origin, so a request claiming |
| 13 | // "same-origin" would pass with a foreign Origin. Here the Origin |
| 14 | // header alone decides. |
| 15 | func originCheck(origin string) func(http.Handler) http.Handler { |
| 16 | return func(next http.Handler) http.Handler { |
| 17 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 18 | if r.Method != http.MethodGet && r.Method != http.MethodHead && r.Method != http.MethodOptions { |
| 19 | if o := r.Header.Get("Origin"); o != "" && o != origin { |
| 20 | http.Error(w, "cross-origin form submission refused", http.StatusForbidden) |
| 21 | return |
| 22 | } |
| 23 | } |
| 24 | next.ServeHTTP(w, r) |
| 25 | }) |
| 26 | } |
| 27 | } |
| 28 | |