diff --git a/cmd/anubis/main.go b/cmd/anubis/main.go index 7bb20c65..beae5347 100644 --- a/cmd/anubis/main.go +++ b/cmd/anubis/main.go @@ -51,6 +51,7 @@ var ( cookiePrefix = flag.String("cookie-prefix", "techaro.lol-anubis", "prefix for browser cookies created by Anubis") cookiePartitioned = flag.Bool("cookie-partitioned", false, "if true, sets the partitioned flag on Anubis cookies, enabling CHIPS support") hs512Secret = flag.String("hs512-secret", "", "secret used to sign JWTs, uses ed25519 if not set") + cookieSecure = flag.Bool("cookie-secure", true, "if true, sets the secure flag on Anubis cookies") ed25519PrivateKeyHex = flag.String("ed25519-private-key-hex", "", "private key used to sign JWTs, if not set a random one will be assigned") ed25519PrivateKeyHexFile = flag.String("ed25519-private-key-hex-file", "", "file name containing value for ed25519-private-key-hex") metricsBind = flag.String("metrics-bind", ":9090", "network address to bind metrics to") @@ -403,6 +404,7 @@ func main() { Target: *target, WebmasterEmail: *webmasterEmail, OpenGraph: policy.OpenGraph, + CookieSecure: *cookieSecure, }) if err != nil { log.Fatalf("can't construct libanubis.Server: %v", err) diff --git a/lib/config.go b/lib/config.go index 4c322f3f..b4f1b910 100644 --- a/lib/config.go +++ b/lib/config.go @@ -44,6 +44,7 @@ type Options struct { StripBasePrefix bool OpenGraph config.OpenGraph ServeRobotsTXT bool + CookieSecure bool } func LoadPoliciesOrDefault(ctx context.Context, fname string, defaultDifficulty int) (*policy.ParsedConfig, error) { diff --git a/lib/http.go b/lib/http.go index 0d8d9e76..fd2056b0 100644 --- a/lib/http.go +++ b/lib/http.go @@ -23,10 +23,11 @@ import ( var domainMatchRegexp = regexp.MustCompile(`^((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$`) type CookieOpts struct { - Value string - Host string - Path string - Name string + Value string + Host string + Path string + Name string + Expiry time.Duration } func (s *Server) SetCookie(w http.ResponseWriter, cookieOpts CookieOpts) { @@ -45,12 +46,17 @@ func (s *Server) SetCookie(w http.ResponseWriter, cookieOpts CookieOpts) { } } + if cookieOpts.Expiry == 0 { + cookieOpts.Expiry = s.opts.CookieExpiration + } + http.SetCookie(w, &http.Cookie{ Name: name, Value: cookieOpts.Value, - Expires: time.Now().Add(s.opts.CookieExpiration), - SameSite: http.SameSiteLaxMode, + Expires: time.Now().Add(cookieOpts.Expiry), + SameSite: http.SameSiteNoneMode, Domain: domain, + Secure: s.opts.CookieSecure, Partitioned: s.opts.CookiePartitioned, Path: path, }) @@ -77,9 +83,10 @@ func (s *Server) ClearCookie(w http.ResponseWriter, cookieOpts CookieOpts) { Value: "", MaxAge: -1, Expires: time.Now().Add(-1 * time.Minute), - SameSite: http.SameSiteLaxMode, + SameSite: http.SameSiteNoneMode, Partitioned: s.opts.CookiePartitioned, Domain: domain, + Secure: s.opts.CookieSecure, Path: path, }) } @@ -132,11 +139,12 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, rule *polic } } - http.SetCookie(w, &http.Cookie{ - Name: anubis.TestCookieName, - Value: challengeStr, - Expires: time.Now().Add(30 * time.Minute), - Path: "/", + s.SetCookie(w, CookieOpts{ + Value: challengeStr, + Host: r.Host, + Path: "/", + Name: anubis.TestCookieName, + Expiry: 30 * time.Minute, }) impl, ok := challenge.Get(rule.Challenge.Algorithm)