Skip to content

Commit 920c346

Browse files
gavinkflammelsal13
authored andcommitted
fix: add validation for duplicated API keys (#5955)
* reject duplicated API keys * enhance api-key-auth e2e test to cover duplicated client IDs Signed-off-by: Gavin Lam <[email protected]> Signed-off-by: melsal13 <[email protected]>
1 parent 0938ca0 commit 920c346

File tree

5 files changed

+267
-0
lines changed

5 files changed

+267
-0
lines changed

internal/gatewayapi/securitypolicy.go

+9
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,8 @@ func (t *Translator) buildAPIKeyAuth(
11241124
}
11251125

11261126
credentials := make(map[string]ir.PrivateBytes)
1127+
seenKeys := make(sets.Set[string])
1128+
11271129
for _, ref := range policy.Spec.APIKeyAuth.CredentialRefs {
11281130
credentialsSecret, err := t.validateSecretRef(
11291131
false, from, ref, resources)
@@ -1134,6 +1136,13 @@ func (t *Translator) buildAPIKeyAuth(
11341136
if _, ok := credentials[clientid]; ok {
11351137
continue
11361138
}
1139+
1140+
keyString := string(key)
1141+
if seenKeys.Has(keyString) {
1142+
return nil, errors.New("duplicated API key")
1143+
}
1144+
1145+
seenKeys.Insert(keyString)
11371146
credentials[clientid] = key
11381147
}
11391148
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
gateways:
2+
- apiVersion: gateway.networking.k8s.io/v1
3+
kind: Gateway
4+
metadata:
5+
namespace: envoy-gateway
6+
name: gateway-1
7+
spec:
8+
gatewayClassName: envoy-gateway-class
9+
listeners:
10+
- name: http
11+
protocol: HTTP
12+
port: 80
13+
hostname: "*.envoyproxy.io"
14+
allowedRoutes:
15+
namespaces:
16+
from: All
17+
httpRoutes:
18+
- apiVersion: gateway.networking.k8s.io/v1
19+
kind: HTTPRoute
20+
metadata:
21+
namespace: default
22+
name: httproute-1
23+
spec:
24+
hostnames:
25+
- gateway.envoyproxy.io
26+
parentRefs:
27+
- namespace: envoy-gateway
28+
name: gateway-1
29+
sectionName: http
30+
rules:
31+
- matches:
32+
- path:
33+
value: "/"
34+
backendRefs:
35+
- name: service-1
36+
port: 8080
37+
securityPolicies:
38+
- apiVersion: gateway.envoyproxy.io/v1alpha1
39+
kind: SecurityPolicy
40+
metadata:
41+
namespace: default
42+
name: policy-for-route-1
43+
spec:
44+
targetRefs:
45+
- group: gateway.networking.k8s.io
46+
kind: HTTPRoute
47+
name: httproute-1
48+
apiKeyAuth:
49+
extractFrom:
50+
- headers: ["X-API-KEY"]
51+
credentialRefs:
52+
- name: "credential-1"
53+
secrets:
54+
- apiVersion: v1
55+
kind: Secret
56+
metadata:
57+
namespace: default
58+
name: credential-1
59+
data:
60+
client1: "a2V5MQ=="
61+
client2: "a2V5Mg=="
62+
client3: "a2V5Mg=="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
gateways:
2+
- apiVersion: gateway.networking.k8s.io/v1
3+
kind: Gateway
4+
metadata:
5+
creationTimestamp: null
6+
name: gateway-1
7+
namespace: envoy-gateway
8+
spec:
9+
gatewayClassName: envoy-gateway-class
10+
listeners:
11+
- allowedRoutes:
12+
namespaces:
13+
from: All
14+
hostname: '*.envoyproxy.io'
15+
name: http
16+
port: 80
17+
protocol: HTTP
18+
status:
19+
listeners:
20+
- attachedRoutes: 1
21+
conditions:
22+
- lastTransitionTime: null
23+
message: Sending translated listener configuration to the data plane
24+
reason: Programmed
25+
status: "True"
26+
type: Programmed
27+
- lastTransitionTime: null
28+
message: Listener has been successfully translated
29+
reason: Accepted
30+
status: "True"
31+
type: Accepted
32+
- lastTransitionTime: null
33+
message: Listener references have been resolved
34+
reason: ResolvedRefs
35+
status: "True"
36+
type: ResolvedRefs
37+
name: http
38+
supportedKinds:
39+
- group: gateway.networking.k8s.io
40+
kind: HTTPRoute
41+
- group: gateway.networking.k8s.io
42+
kind: GRPCRoute
43+
httpRoutes:
44+
- apiVersion: gateway.networking.k8s.io/v1
45+
kind: HTTPRoute
46+
metadata:
47+
creationTimestamp: null
48+
name: httproute-1
49+
namespace: default
50+
spec:
51+
hostnames:
52+
- gateway.envoyproxy.io
53+
parentRefs:
54+
- name: gateway-1
55+
namespace: envoy-gateway
56+
sectionName: http
57+
rules:
58+
- backendRefs:
59+
- name: service-1
60+
port: 8080
61+
matches:
62+
- path:
63+
value: /
64+
status:
65+
parents:
66+
- conditions:
67+
- lastTransitionTime: null
68+
message: Route is accepted
69+
reason: Accepted
70+
status: "True"
71+
type: Accepted
72+
- lastTransitionTime: null
73+
message: Resolved all the Object references for the Route
74+
reason: ResolvedRefs
75+
status: "True"
76+
type: ResolvedRefs
77+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
78+
parentRef:
79+
name: gateway-1
80+
namespace: envoy-gateway
81+
sectionName: http
82+
infraIR:
83+
envoy-gateway/gateway-1:
84+
proxy:
85+
listeners:
86+
- address: null
87+
name: envoy-gateway/gateway-1/http
88+
ports:
89+
- containerPort: 10080
90+
name: http-80
91+
protocol: HTTP
92+
servicePort: 80
93+
metadata:
94+
labels:
95+
gateway.envoyproxy.io/owning-gateway-name: gateway-1
96+
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
97+
name: envoy-gateway/gateway-1
98+
namespace: envoy-gateway-system
99+
securityPolicies:
100+
- apiVersion: gateway.envoyproxy.io/v1alpha1
101+
kind: SecurityPolicy
102+
metadata:
103+
creationTimestamp: null
104+
name: policy-for-route-1
105+
namespace: default
106+
spec:
107+
apiKeyAuth:
108+
credentialRefs:
109+
- group: null
110+
kind: null
111+
name: credential-1
112+
extractFrom:
113+
- headers:
114+
- X-API-KEY
115+
targetRefs:
116+
- group: gateway.networking.k8s.io
117+
kind: HTTPRoute
118+
name: httproute-1
119+
status:
120+
ancestors:
121+
- ancestorRef:
122+
group: gateway.networking.k8s.io
123+
kind: Gateway
124+
name: gateway-1
125+
namespace: envoy-gateway
126+
sectionName: http
127+
conditions:
128+
- lastTransitionTime: null
129+
message: 'APIKeyAuth: duplicated API key.'
130+
reason: Invalid
131+
status: "False"
132+
type: Accepted
133+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
134+
xdsIR:
135+
envoy-gateway/gateway-1:
136+
accessLog:
137+
json:
138+
- path: /dev/stdout
139+
http:
140+
- address: 0.0.0.0
141+
hostnames:
142+
- '*.envoyproxy.io'
143+
isHTTP2: false
144+
metadata:
145+
kind: Gateway
146+
name: gateway-1
147+
namespace: envoy-gateway
148+
sectionName: http
149+
name: envoy-gateway/gateway-1/http
150+
path:
151+
escapedSlashesAction: UnescapeAndRedirect
152+
mergeSlashes: true
153+
port: 10080
154+
routes:
155+
- destination:
156+
name: httproute/default/httproute-1/rule/0
157+
settings:
158+
- addressType: IP
159+
endpoints:
160+
- host: 7.7.7.7
161+
port: 8080
162+
name: httproute/default/httproute-1/rule/0/backend/0
163+
protocol: HTTP
164+
weight: 1
165+
directResponse:
166+
statusCode: 500
167+
hostname: gateway.envoyproxy.io
168+
isHTTP2: false
169+
metadata:
170+
kind: HTTPRoute
171+
name: httproute-1
172+
namespace: default
173+
name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
174+
pathMatch:
175+
distinct: false
176+
name: ""
177+
prefix: /
178+
security: {}
179+
readyListener:
180+
address: 0.0.0.0
181+
ipFamily: IPv4
182+
path: /ready
183+
port: 19003

release-notes/current.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ new features: |
1313
bug fixes: |
1414
Fix reference grant from SecurityPolicy to referenced remoteJWKS backend not respected.
1515
Added validation for header values.
16+
Added validation for duplicated API keys.
1617
1718
# Enhancements that improve performance.
1819
performance improvements: |

test/e2e/testdata/api-key-auth.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ data:
1010
# key2
1111
client2: "a2V5Mg=="
1212
---
13+
apiVersion: v1
14+
kind: Secret
15+
metadata:
16+
namespace: gateway-conformance-infra
17+
name: api-key-auth-users-secret-2
18+
data:
19+
# key2 - duplicate client id should be ignored
20+
client1: "a2V5Mg=="
21+
---
1322
apiVersion: gateway.networking.k8s.io/v1
1423
kind: HTTPRoute
1524
metadata:
@@ -76,6 +85,7 @@ spec:
7685
- headers: ["X-API-KEY"]
7786
credentialRefs:
7887
- name: "api-key-auth-users-secret-1"
88+
- name: "api-key-auth-users-secret-2"
7989
---
8090
apiVersion: gateway.envoyproxy.io/v1alpha1
8191
kind: SecurityPolicy
@@ -92,6 +102,7 @@ spec:
92102
- cookies: ["X-API-KEY"]
93103
credentialRefs:
94104
- name: "api-key-auth-users-secret-1"
105+
- name: "api-key-auth-users-secret-2"
95106

96107
---
97108
apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -109,3 +120,4 @@ spec:
109120
- params: ["X-API-KEY"]
110121
credentialRefs:
111122
- name: "api-key-auth-users-secret-1"
123+
- name: "api-key-auth-users-secret-2"

0 commit comments

Comments
 (0)