serveHTTP is the internal entry point for API requests. It may be called more than once per request, for example if a request is rewritten (i.e. internal redirect).
(w http.ResponseWriter, r *http.Request)
| 810 | // be called more than once per request, for example if a request |
| 811 | // is rewritten (i.e. internal redirect). |
| 812 | func (h adminHandler) serveHTTP(w http.ResponseWriter, r *http.Request) { |
| 813 | if h.remoteControl != nil { |
| 814 | // enforce access controls on secure endpoint |
| 815 | if err := h.remoteControl.enforceAccessControls(r); err != nil { |
| 816 | h.handleError(w, r, err) |
| 817 | return |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | // common mitigations in browser contexts |
| 822 | if strings.Contains(r.Header.Get("Upgrade"), "websocket") { |
| 823 | // I've never been able demonstrate a vulnerability myself, but apparently |
| 824 | // WebSocket connections originating from browsers aren't subject to CORS |
| 825 | // restrictions, so we'll just be on the safe side |
| 826 | h.handleError(w, r, APIError{ |
| 827 | HTTPStatus: http.StatusBadRequest, |
| 828 | Err: errors.New("websocket connections aren't allowed"), |
| 829 | Message: "WebSocket connections aren't allowed.", |
| 830 | }) |
| 831 | return |
| 832 | } |
| 833 | if strings.Contains(r.Header.Get("Sec-Fetch-Mode"), "no-cors") { |
| 834 | // turns out web pages can just disable the same-origin policy (!???!?) |
| 835 | // but at least browsers let us know that's the case, holy heck |
| 836 | h.handleError(w, r, APIError{ |
| 837 | HTTPStatus: http.StatusBadRequest, |
| 838 | Err: errors.New("client attempted to make request by disabling same-origin policy using no-cors mode"), |
| 839 | Message: "Disabling same-origin restrictions is not allowed.", |
| 840 | }) |
| 841 | return |
| 842 | } |
| 843 | if r.Header.Get("Origin") == "null" { |
| 844 | // bug in Firefox in certain cross-origin situations (yikes?) |
| 845 | // (not strictly a security vuln on its own, but it's red flaggy, |
| 846 | // since it seems to manifest in cross-origin contexts) |
| 847 | h.handleError(w, r, APIError{ |
| 848 | HTTPStatus: http.StatusBadRequest, |
| 849 | Err: errors.New("invalid origin 'null'"), |
| 850 | Message: "Buggy browser is sending null Origin header.", |
| 851 | }) |
| 852 | return |
| 853 | } |
| 854 | |
| 855 | if h.enforceHost { |
| 856 | // DNS rebinding mitigation |
| 857 | err := h.checkHost(r) |
| 858 | if err != nil { |
| 859 | h.handleError(w, r, err) |
| 860 | return |
| 861 | } |
| 862 | } |
| 863 | |
| 864 | _, hasOriginHeader := r.Header["Origin"] |
| 865 | _, hasSecHeader := r.Header["Sec-Fetch-Mode"] |
| 866 | if h.enforceOrigin || hasOriginHeader || hasSecHeader { |
| 867 | // cross-site mitigation |
| 868 | origin, err := h.checkOrigin(r) |
| 869 | if err != nil { |
no test coverage detected