git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add validation for Headers struct
commitd26c65ba8d3f487eb4535e246e750ae664977c56 authorJoel Speed <joel.speed@hotmail.co.uk> dateThu 23 Jul 2020, 10:47 (6 years ago) parent2dc0d1e
4 files changed+120
pkg/validation/common.go+44 pkg/validation/header.go+63 pkg/validation/options.go+2 pkg/validation/utils.go+11
pkg/validation/common.gonew file+44
@@ -0,0 +1,44 @@
1+package validation
2+
3+import (
4+ "encoding/base64"
5+ "fmt"
6+ "os"
7+
8+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
9+)
10+
11+func validateSecretSource(source options.SecretSource) string {
12+ switch {
13+ case len(source.Value) > 0 && source.FromEnv == "" && source.FromFile == "":
14+ return validateSecretSourceValue(source.Value)
15+ case len(source.Value) == 0 && source.FromEnv != "" && source.FromFile == "":
16+ return validateSecretSourceEnv(source.FromEnv)
17+ case len(source.Value) == 0 && source.FromEnv == "" && source.FromFile != "":
18+ return validateSecretSourceFile(source.FromFile)
19+ default:
20+ return "multiple values specified for secret source: specify either value, fromEnv of fromFile"
21+ }
22+}
23+
24+func validateSecretSourceValue(value []byte) string {
25+ dst := make([]byte, len(value))
26+ if _, err := base64.StdEncoding.Decode(dst, value); err != nil {
27+ return fmt.Sprintf("error decoding secret value: %v", err)
28+ }
29+ return ""
30+}
31+
32+func validateSecretSourceEnv(key string) string {
33+ if value := os.Getenv(key); value == "" {
34+ return fmt.Sprintf("error loading secret from environent: no value for for key %q", key)
35+ }
36+ return ""
37+}
38+
39+func validateSecretSourceFile(path string) string {
40+ if _, err := os.Stat(path); err != nil {
41+ return fmt.Sprintf("error loadig secret from file: %v", err)
42+ }
43+ return ""
44+}
pkg/validation/header.gonew file+63
@@ -0,0 +1,63 @@
1+package validation
2+
3+import (
4+ "fmt"
5+
6+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
7+)
8+
9+func validateHeaders(headers []options.Header) []string {
10+ msgs := []string{}
11+ names := make(map[string]struct{})
12+
13+ for _, header := range headers {
14+ msgs = append(msgs, validateHeader(header, names)...)
15+ }
16+ return msgs
17+}
18+
19+func validateHeader(header options.Header, names map[string]struct{}) []string {
20+ msgs := []string{}
21+
22+ if header.Name == "" {
23+ msgs = append(msgs, "header has empty name: names are required for all headers")
24+ }
25+
26+ if _, ok := names[header.Name]; ok {
27+ msgs = append(msgs, fmt.Sprintf("multiple headers found with name %q: header names must be unique", header.Name))
28+ }
29+ names[header.Name] = struct{}{}
30+
31+ for _, value := range header.Values {
32+ msgs = append(msgs,
33+ prefixValues(fmt.Sprintf("invalid header %q: invalid values: ", header.Name),
34+ validateHeaderValue(header.Name, value)...,
35+ )...,
36+ )
37+ }
38+ return msgs
39+}
40+
41+func validateHeaderValue(name string, value options.HeaderValue) []string {
42+ switch {
43+ case value.SecretSource != nil && value.ClaimSource == nil:
44+ return []string{validateSecretSource(*value.SecretSource)}
45+ case value.SecretSource == nil && value.ClaimSource != nil:
46+ return validateHeaderValueClaimSource(*value.ClaimSource)
47+ default:
48+ return []string{"header value has multiple entries: only one entry per value is allowed"}
49+ }
50+}
51+
52+func validateHeaderValueClaimSource(claim options.ClaimSource) []string {
53+ msgs := []string{}
54+
55+ if claim.Claim == "" {
56+ msgs = append(msgs, "claim should not be empty")
57+ }
58+
59+ if claim.BasicAuthPassword != nil {
60+ msgs = append(msgs, prefixValues("invalid basicAuthPassword: ", validateSecretSource(*claim.BasicAuthPassword))...)
61+ }
62+ return msgs
63+}
pkg/validation/options.go+2
@@ -28,6 +28,8 @@ func Validate(o *options.Options) error {
2828 msgs := validateCookie(o.Cookie)
2929 msgs = append(msgs, validateSessionCookieMinimal(o)...)
3030 msgs = append(msgs, validateRedisSessionStore(o)...)
31+ msgs = append(msgs, prefixValues("injectRequestHeaders: ", validateHeaders(o.InjectRequestHeaders)...)...)
32+ msgs = append(msgs, prefixValues("injectRespeonseHeaders: ", validateHeaders(o.InjectRequestHeaders)...)...)
3133
3234 if o.SSLInsecureSkipVerify {
3335 // InsecureSkipVerify is a configurable option we allow
pkg/validation/utils.gonew file+11
@@ -0,0 +1,11 @@
1+package validation
2+
3+func prefixValues(prefix string, values ...string) []string {
4+ msgs := []string{}
5+ for _, value := range values {
6+ if value != "" {
7+ msgs = append(msgs, prefix+value)
8+ }
9+ }
10+ return msgs
11+}