Commit b00bc407 authored by Hector Sanjuan's avatar Hector Sanjuan

http: block all ^Mozilla user agents without Origin nor Referer

parent cd51b41f
...@@ -15,19 +15,6 @@ const ( ...@@ -15,19 +15,6 @@ const (
ACACredentials = "Access-Control-Allow-Credentials" ACACredentials = "Access-Control-Allow-Credentials"
) )
// disallowedUserAgents specifies a denylist of user agents that are not
// allowed to perform POST requests if they are not providing Origin
// and/or Referer headers. As mitigation for things like
// https://bugzilla.mozilla.org/show_bug.cgi?id=429594. Defaults to
// Firefox-related things. The matching against the user-agent string
// is made with strings.Contains().
var disallowedUserAgents = []string{
"Firefox",
"Focus",
"Klar",
"FxiOS",
}
type ServerConfig struct { type ServerConfig struct {
// APIPath is the prefix of all request paths. // APIPath is the prefix of all request paths.
// Example: host:port/api/v0/add. Here the APIPath is /api/v0 // Example: host:port/api/v0/add. Here the APIPath is /api/v0
...@@ -44,14 +31,6 @@ type ServerConfig struct { ...@@ -44,14 +31,6 @@ type ServerConfig struct {
// websites to include resources from the API but not _read_ them. // websites to include resources from the API but not _read_ them.
AllowGet bool AllowGet bool
// DisallowUserAgents specifies a blacklist of user agents that are not
// allowed to perform POST requests if they are not providing Origin
// and/or Referer headers. As mitigation for things like
// https://bugzilla.mozilla.org/show_bug.cgi?id=429594.
// Defaults to ["Firefox"]. The matching against the user-agent
// string is made with strings.Contains().
DisallowUserAgents []string
// corsOpts is a set of options for CORS headers. // corsOpts is a set of options for CORS headers.
corsOpts *cors.Options corsOpts *cors.Options
...@@ -191,12 +170,15 @@ func allowUserAgent(r *http.Request, cfg *ServerConfig) bool { ...@@ -191,12 +170,15 @@ func allowUserAgent(r *http.Request, cfg *ServerConfig) bool {
return true return true
} }
// If not, check that request is not from a blacklisted UA. // Allow if the user agent does not start with Mozilla... (i.e. curl)
ua := r.Header.Get("User-agent") ua := r.Header.Get("User-agent")
for _, forbiddenUA := range disallowedUserAgents { if !strings.HasPrefix(ua, "Mozilla") {
if strings.Contains(ua, forbiddenUA) { return true
return false
}
} }
return true
// Disallow otherwise.
//
// This means the request probably came from a browser and thus, it
// should have included Origin or referer headers.
return false
} }
...@@ -174,7 +174,7 @@ func TestUnhandledMethod(t *testing.T) { ...@@ -174,7 +174,7 @@ func TestUnhandledMethod(t *testing.T) {
func TestDisallowedUserAgents(t *testing.T) { func TestDisallowedUserAgents(t *testing.T) {
tcs := []httpTestCase{ tcs := []httpTestCase{
{ {
// Block Firefox // Block Mozilla* browsers that do not provide origins.
Method: "POST", Method: "POST",
AllowGet: false, AllowGet: false,
Code: http.StatusForbidden, Code: http.StatusForbidden,
...@@ -192,10 +192,13 @@ func TestDisallowedUserAgents(t *testing.T) { ...@@ -192,10 +192,13 @@ func TestDisallowedUserAgents(t *testing.T) {
}, },
}, },
{ {
// Do not block Chrome // Do not block a Mozilla* browser that provides an
Method: "POST", // allowed Origin
AllowGet: false, Method: "POST",
Code: http.StatusOK, AllowGet: false,
AllowOrigins: []string{"*"},
Origin: "null",
Code: http.StatusOK,
ReqHeaders: map[string]string{ ReqHeaders: map[string]string{
"User-Agent": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", "User-Agent": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
}, },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment