checker-http/checker/rules_cookies.go

70 lines
2.2 KiB
Go

// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2026 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
package checker
import (
"context"
"fmt"
"strings"
sdk "git.happydns.org/checker-sdk-go/checker"
)
func init() { RegisterRule(&cookieFlagsRule{}) }
// cookieFlagsRule audits Set-Cookie attributes on HTTPS responses: every
// cookie should be Secure and HttpOnly, and SameSite should be set.
type cookieFlagsRule struct{}
func (r *cookieFlagsRule) Name() string { return "http.cookie_flags" }
func (r *cookieFlagsRule) Description() string {
return "Verifies that cookies set over HTTPS use the Secure, HttpOnly and SameSite attributes."
}
func (r *cookieFlagsRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState {
data, errSt := loadHTTPData(ctx, obs)
if errSt != nil {
return []sdk.CheckState{*errSt}
}
probes := successfulHTTPSProbes(data.Probes)
if len(probes) == 0 {
return []sdk.CheckState{unknownState("http.cookie_flags.no_https", "No successful HTTPS probe to evaluate.")}
}
var states []sdk.CheckState
totalCookies := 0
for _, p := range probes {
for _, c := range p.Cookies {
totalCookies++
var issues []string
if !c.Secure {
issues = append(issues, "missing Secure")
}
if !c.HttpOnly {
issues = append(issues, "missing HttpOnly")
}
if c.SameSite == "" {
issues = append(issues, "missing SameSite")
} else if strings.EqualFold(c.SameSite, "None") && !c.Secure {
issues = append(issues, "SameSite=None requires Secure")
}
if len(issues) > 0 {
states = append(states, sdk.CheckState{
Status: sdk.StatusWarn,
Code: "http.cookie_flags.weak",
Subject: fmt.Sprintf("%s :: %s", p.Address, c.Name),
Message: fmt.Sprintf("Cookie %q on %s: %s", c.Name, p.Address, strings.Join(issues, ", ")),
})
}
}
}
if totalCookies == 0 {
return []sdk.CheckState{passState("http.cookie_flags.none", "No cookies were set on the inspected responses.")}
}
if len(states) == 0 {
return []sdk.CheckState{passState("http.cookie_flags.ok", fmt.Sprintf("All %d cookies have proper Secure/HttpOnly/SameSite flags.", totalCookies))}
}
return states
}