git.iko.soy/typeable/oauth2-proxy
on master help sign in
Move CookieOptions validation to it's own file
commit900061b88a59dcd79b462efb3ba57b6ca21b1663 authorJoel Speed <joel.speed@hotmail.co.uk> dateSun 24 May 2020, 11:16 (6 years ago) parentb3ba259
2 files changed+71−56
pkg/validation/cookie.go+69 pkg/validation/options.go+2−56
pkg/validation/cookie.gonew file+69
@@ -0,0 +1,69 @@
1+package validation
2+
3+import (
4+ "fmt"
5+ "net/http"
6+ "sort"
7+
8+ "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
9+ "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
10+)
11+
12+func validateCookieOptions(o options.CookieOptions) []string {
13+ msgs := validateCookieSecret(o.Secret)
14+
15+ if o.Refresh >= o.Expire {
16+ msgs = append(msgs, fmt.Sprintf(
17+ "cookie_refresh (%q) must be less than cookie_expire (%q)",
18+ o.Refresh.String(),
19+ o.Expire.String()))
20+ }
21+
22+ switch o.SameSite {
23+ case "", "none", "lax", "strict":
24+ default:
25+ msgs = append(msgs, fmt.Sprintf("cookie_samesite (%q) must be one of ['', 'lax', 'strict', 'none']", o.SameSite))
26+ }
27+
28+ // Sort cookie domains by length, so that we try longer (and more specific) domains first
29+ sort.Slice(o.Domains, func(i, j int) bool {
30+ return len(o.Domains[i]) > len(o.Domains[j])
31+ })
32+
33+ msgs = append(msgs, validateCookieName(o.Name)...)
34+ return msgs
35+}
36+
37+func validateCookieName(name string) []string {
38+ cookie := &http.Cookie{Name: name}
39+ if cookie.String() == "" {
40+ return []string{fmt.Sprintf("invalid cookie name: %q", name)}
41+ }
42+ return []string{}
43+}
44+
45+func validateCookieSecret(secret string) []string {
46+ if secret == "" {
47+ return []string{"missing setting: cookie-secret"}
48+ }
49+
50+ secretBytes := encryption.SecretBytes(secret)
51+ // Check if the secret is a valid length
52+ switch len(secretBytes) {
53+ case 16, 24, 32:
54+ // Valid secret size found
55+ return []string{}
56+ }
57+ // Invalid secret size found, return a message
58+
59+ // If the secretBytes is different to the raw secret, it was decoded from Base64
60+ // Add a note to the error message
61+ var decodedSuffix string
62+ if string(secretBytes) != secret {
63+ decodedSuffix = " note: cookie secret was base64 decoded"
64+ }
65+
66+ return []string{fmt.Sprintf(
67+ "cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is %d bytes.%s",
68+ len(secretBytes), decodedSuffix)}
69+}
pkg/validation/options.go+2−56
@@ -10,14 +10,12 @@ import (
1010 "net/url"
1111 "os"
1212 "regexp"
13− "sort"
1413 "strings"
1514
1615 "github.com/coreos/go-oidc"
1716 "github.com/dgrijalva/jwt-go"
1817 "github.com/mbland/hmacauth"
1918 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
20− "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
2119 "github.com/oauth2-proxy/oauth2-proxy/pkg/ip"
2220 "github.com/oauth2-proxy/oauth2-proxy/pkg/logger"
2321 "github.com/oauth2-proxy/oauth2-proxy/pkg/requests"
@@ -28,7 +26,8 @@ import (
2826// Validate checks that required options are set and validates those that they
2927// are of the correct format
3028func Validate(o *options.Options) error {
31− msgs := make([]string, 0)
29+ msgs := validateCookieOptions(o.Cookie)
30+
3231 if o.SSLInsecureSkipVerify {
3332 insecureTransport := &http.Transport{
3433 TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
@@ -49,30 +48,6 @@ func Validate(o *options.Options) error {
4948 }
5049 }
5150
52− if o.Cookie.Secret == "" {
53− msgs = append(msgs, "missing setting: cookie-secret")
54− } else {
55− validCookieSecretSize := false
56− for _, i := range []int{16, 24, 32} {
57− if len(encryption.SecretBytes(o.Cookie.Secret)) == i {
58− validCookieSecretSize = true
59− }
60− }
61− var decoded bool
62− if string(encryption.SecretBytes(o.Cookie.Secret)) != o.Cookie.Secret {
63− decoded = true
64− }
65− if !validCookieSecretSize {
66− var suffix string
67− if decoded {
68− suffix = " note: cookie secret was base64 decoded"
69− }
70− msgs = append(msgs,
71− fmt.Sprintf("Cookie secret must be 16, 24, or 32 bytes to create an AES cipher. Got %d bytes.%s",
72− len(encryption.SecretBytes(o.Cookie.Secret)), suffix))
73− }
74− }
75−
7651 if o.ClientID == "" {
7752 msgs = append(msgs, "missing setting: client-id")
7853 }
@@ -222,14 +197,6 @@ func Validate(o *options.Options) error {
222197 }
223198 msgs = parseProviderInfo(o, msgs)
224199
225− if o.Cookie.Refresh >= o.Cookie.Expire {
226− msgs = append(msgs, fmt.Sprintf(
227− "cookie_refresh (%s) must be less than "+
228− "cookie_expire (%s)",
229− o.Cookie.Refresh.String(),
230− o.Cookie.Expire.String()))
231− }
232−
233200 if len(o.GoogleGroups) > 0 || o.GoogleAdminEmail != "" || o.GoogleServiceAccountJSON != "" {
234201 if len(o.GoogleGroups) < 1 {
235202 msgs = append(msgs, "missing setting: google-group")
@@ -242,20 +209,7 @@ func Validate(o *options.Options) error {
242209 }
243210 }
244211
245− switch o.Cookie.SameSite {
246− case "", "none", "lax", "strict":
247− default:
248− msgs = append(msgs, fmt.Sprintf("cookie_samesite (%s) must be one of ['', 'lax', 'strict', 'none']", o.Cookie.SameSite))
249− }
250−
251− // Sort cookie domains by length, so that we try longer (and more specific)
252− // domains first
253− sort.Slice(o.Cookie.Domains, func(i, j int) bool {
254− return len(o.Cookie.Domains[i]) > len(o.Cookie.Domains[j])
255− })
256−
257212 msgs = parseSignatureKey(o, msgs)
258− msgs = validateCookieName(o, msgs)
259213 msgs = configureLogger(o.Logging, msgs)
260214
261215 if o.ReverseProxy {
@@ -442,14 +396,6 @@ func newVerifierFromJwtIssuer(jwtIssuer jwtIssuer) (*oidc.IDTokenVerifier, error
442396 return verifier, nil
443397}
444398
445−func validateCookieName(o *options.Options, msgs []string) []string {
446− cookie := &http.Cookie{Name: o.Cookie.Name}
447− if cookie.String() == "" {
448− return append(msgs, fmt.Sprintf("invalid cookie name: %q", o.Cookie.Name))
449− }
450− return msgs
451−}
452−
453399// jwtIssuer hold parsed JWT issuer info that's used to construct a verifier.
454400type jwtIssuer struct {
455401 issuerURI string