ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / internal/platform/security/csrf.go

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / internal/platform/security/csrf.go
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberinternal/platform/security/csrf.go
Original SHA-2565379cd0d854f9f18511ae89a8a1ea55b1cb9a3e6c77f5c457649fc7bb131bc89
Git blob SHAd88e3de3bb230b1fe88552e986a08889e7ff70e7
Reading-copy SHA-2565379cd0d854f9f18511ae89a8a1ea55b1cb9a3e6c77f5c457649fc7bb131bc89

Original source ↗

Every recorded occurrence

These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.

Original recordBranch or archiveRevision / identifierOriginal location
Janady13/missionmatch / internal/platform/security/csrf.gofeature/opportunity-to-outcome720d47fae476b0d38477ae4401697d372b1ea2bcOpen original
Janady13/missionmatch / internal/platform/security/csrf.gofeature/aioe-upgrade2178e7298d0e5d9af83afa12402fd587f0ba6ed8Open original

Recovered source transcript

package security import ( "crypto/hmac" "crypto/rand" "crypto/sha256" "crypto/subtle" "encoding/base64" "net/http" "strings" ) // CSRF issues and verifies signed double submit tokens. A token is a random nonce plus an HMAC over // that nonce AND the session the token was minted for, so a value the server did not mint (for // example a cookie planted by a compromised sibling subdomain) is rejected even though the double // submit cookie and header match, and a token minted for one session is refused when replayed on // another. This composes with the __Host- cookie prefix, SameSite Strict on the session, and the // Origin allowlist below. // // The session binding is what makes signed double submit actually a defense rather than a signature // over a value the attacker also gets to choose. Without it, anybody able to reach GET /auth/csrf, // which is unauthenticated by necessity because the login form needs a token, could mint a // structurally valid pair and plant it on a victim, and the signature proved only that the SERVER // had minted the value at some point, not that it had minted it for THIS session. type CSRF struct{ key []byte } // NewCSRF builds a CSRF signer. A nil or empty key disables verification (dev only); production // config requires the key. func NewCSRF(key []byte) *CSRF { return &CSRF{key: key} } // Issue mints a fresh token bound to sessionToken, to set as the __Host-mm_csrf cookie and echo in // the X-CSRF-Token header. An empty sessionToken is the anonymous binding used before login; such a // token stops validating the moment a session cookie exists, which is correct, and the SPA already // re mints once on a 403 for an unsafe verb, so the login and MFA transitions cost one retry rather // than an error the user sees. func (c *CSRF) Issue(sessionToken string) (string, error) { nonce := make([]byte, 16) if _, err := rand.Read(nonce); err != nil { return "", err } nb := base64.RawURLEncoding.EncodeToString(nonce) return nb + "." + c.sign(nb, sessionToken), nil } // Valid reports whether token was minted by this signer FOR this session. A token in the old // unbound format fails here rather than being accepted for compatibility: the whole point of the // change is that an unbound token proves nothing, so honoring one would keep the hole open for the // lifetime of every already issued cookie. It fails closed, and the SPA re mints on the 403. func (c *CSRF) Valid(token, sessionToken string) bool { if len(c.key) == 0 { return true // verification disabled (dev) } nb, sig, found := strings.Cut(token, ".") if !found || nb == "" { return false } return subtle.ConstantTimeCompare([]byte(sig), []byte(c.sign(nb, sessionToken))) == 1 } // sign covers the nonce and the session binding under one MAC. The session token is folded in as its // SHA 256 hash, the same form the sessions table stores, so the raw cookie value is never a MAC // input and the CSRF key never sees the live session secret. The two fields are separated by a byte // that cannot occur in base64url output, so no pair of (nonce, binding) values can be rearranged // into another pair with the same signing input. func (c *CSRF) sign(nonceB64, sessionToken string) string { mac := hmac.New(sha256.New, c.key) mac.Write([]byte(nonceB64)) mac.Write([]byte{0x1f}) if sessionToken != "" { mac.Write(HashSessionToken(sessionToken)) } return base64.RawURLEncoding.EncodeToString(mac.Sum(nil)) } // Protect is the middleware enforcing CSRF on unsafe verbs: a hard Origin allowlist (reject absent or // mismatched Origin) plus the signed double submit check (the __Host-mm_csrf cookie and the // X-CSRF-Token header must match and be a valid token bound to the request's own session). Safe verbs // pass through. allowedOrigins is matched exactly; an empty list disables the Origin check (dev only). // // sessionCookieName names the session cookie so the binding can be recomputed from the same request // that carries the token. A request with no session cookie verifies against the anonymous binding, // which is what the pre login endpoints need. func (c *CSRF) Protect(cookieName, headerName, sessionCookieName string, allowedOrigins []string) func(http.Handler) http.Handler { allow := make(map[string]bool, len(allowedOrigins)) for _, o := range allowedOrigins { allow[strings.TrimSpace(o)] = true } return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if safeMethod(r.Method) { next.ServeHTTP(w, r) return } if len(allow) > 0 { origin := r.Header.Get("Origin") if origin == "" { origin = originFromReferer(r.Header.Get("Referer")) } if !allow[origin] { http.Error(w, "forbidden", http.StatusForbidden) return } } var session string if sc, serr := r.Cookie(sessionCookieName); serr == nil { session = sc.Value } cookie, err := r.Cookie(cookieName) header := r.Header.Get(headerName) if err != nil || header == "" || subtle.ConstantTimeCompare([]byte(cookie.Value), []byte(header)) != 1 || !c.Valid(header, session) { http.Error(w, "forbidden", http.StatusForbidden) return } next.ServeHTTP(w, r) }) } } func safeMethod(m string) bool { switch m { case http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace: return true } return false } func originFromReferer(referer string) string { if referer == "" { return "" } // Take scheme://host[:port] from a referer URL without importing net/url for this hot path. i := strings.Index(referer, "://") if i < 0 { return "" } rest := referer[i+3:] if j := strings.IndexByte(rest, '/'); j >= 0 { rest = rest[:j] } return referer[:i+3] + rest }

Search equations, builds, manuscript text, and recovered sources.