An unset WEBHOOKER_ENVIRONMENT now resolves to prod rather than dev, so an operator who forgets the variable is not silently permissive. The only behaviour dev still changes is the CORS middleware, which answers every origin with Access-Control-Allow-Origin: *; that is now off unless dev is set explicitly. Cookie Secure and CSRF strictness are decided per request from the transport and are unaffected. Updated resolveEnvironment and its comment, the README configuration table and prose, and tests covering the default and the explicit dev. Comments that justified behaviour by the old dev default (the TRUSTED_PROXIES warning, a CSRF test) were corrected; that warning still fires in every environment when TRUSTED_PROXIES is empty. Model: opus-4-8
This commit is contained in:
@@ -585,12 +585,14 @@ func resolveMetricsAuth() (string, string, error) {
|
||||
)
|
||||
}
|
||||
|
||||
// resolveEnvironment reads WEBHOOKER_ENVIRONMENT, defaulting to
|
||||
// dev, and rejects unrecognised values.
|
||||
// resolveEnvironment reads WEBHOOKER_ENVIRONMENT, defaulting to prod
|
||||
// when it is unset so a deployment that forgets the variable is not
|
||||
// silently permissive; dev must be set explicitly. It rejects
|
||||
// unrecognised values.
|
||||
func resolveEnvironment() (string, error) {
|
||||
environment := os.Getenv("WEBHOOKER_ENVIRONMENT")
|
||||
if environment == "" {
|
||||
environment = EnvironmentDev
|
||||
environment = EnvironmentProd
|
||||
}
|
||||
|
||||
if environment != EnvironmentDev &&
|
||||
@@ -772,10 +774,10 @@ func (c *Config) warnEgressAllowlist(log *slog.Logger) {
|
||||
// everyone else's wrong passwords, and the receiver's limits become
|
||||
// service-wide ceilings.
|
||||
//
|
||||
// The warning is deliberately not gated on WEBHOOKER_ENVIRONMENT. That
|
||||
// variable defaults to dev, so gating on it would silence the warning
|
||||
// for exactly the operator who forgot to configure the deployment —
|
||||
// the case it exists to catch.
|
||||
// The warning is deliberately not gated on WEBHOOKER_ENVIRONMENT: an
|
||||
// operator who never configured the deployment is exactly the case it
|
||||
// exists to catch, so the exposure it announces is independent of the
|
||||
// environment setting.
|
||||
//
|
||||
// The default of trusting nobody is deliberate — trusting forwarded
|
||||
// headers from arbitrary peers lets any client choose its own bucket —
|
||||
|
||||
@@ -44,9 +44,9 @@ func TestEnvironmentConfig(t *testing.T) {
|
||||
isProd bool
|
||||
}{
|
||||
{
|
||||
name: "default is dev",
|
||||
isDev: true,
|
||||
isProd: false,
|
||||
name: "default is prod",
|
||||
isDev: false,
|
||||
isProd: true,
|
||||
},
|
||||
{
|
||||
name: "explicit dev",
|
||||
@@ -848,10 +848,10 @@ func TestEgressAllowlistWarning(t *testing.T) {
|
||||
// tells an operator a deployment behind a reverse proxy shares one
|
||||
// rate-limit bucket between every client, which turns the receiver
|
||||
// limits into service-wide ceilings and collapses login failure
|
||||
// counting. It must fire whenever TRUSTED_PROXIES is empty,
|
||||
// in any environment: WEBHOOKER_ENVIRONMENT defaults to dev, so gating
|
||||
// on it would silence the warning for exactly the operator who never
|
||||
// configured the deployment. It stays quiet once proxies are named.
|
||||
// counting. It must fire whenever TRUSTED_PROXIES is empty, in any
|
||||
// environment: the warning does not depend on WEBHOOKER_ENVIRONMENT,
|
||||
// since an operator who never configured the deployment is exactly the
|
||||
// one it exists to catch. It stays quiet once proxies are named.
|
||||
func TestSharedRateLimitBucketWarning(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -871,10 +871,9 @@ func TestSharedRateLimitBucketWarning(t *testing.T) {
|
||||
expectWarning: false,
|
||||
},
|
||||
{
|
||||
// The default environment. An internet-exposed
|
||||
// deployment whose operator never set
|
||||
// WEBHOOKER_ENVIRONMENT lands here and has exactly
|
||||
// the exposure the warning announces.
|
||||
// An internet-exposed deployment whose operator set
|
||||
// WEBHOOKER_ENVIRONMENT=dev has exactly the exposure
|
||||
// the warning announces.
|
||||
name: "dev without trusted proxies warns",
|
||||
environment: config.EnvironmentDev,
|
||||
expectWarning: true,
|
||||
|
||||
@@ -380,9 +380,8 @@ func csrfTookStrictPath(
|
||||
|
||||
// TestCSRF_ForwardedProtoSpellingsTakeStrictPath runs the header
|
||||
// spellings a real proxy emits through the middleware. The environment
|
||||
// is dev -- the DEFAULT when WEBHOOKER_ENVIRONMENT is unset -- to pin
|
||||
// that the routing is a per-request transport decision and owes
|
||||
// nothing to configuration.
|
||||
// is set to dev -- the permissive setting -- to pin that the routing is
|
||||
// a per-request transport decision and owes nothing to configuration.
|
||||
func TestCSRF_ForwardedProtoSpellingsTakeStrictPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user