Skip to content

Commit 8e83c4a

Browse files
authored
Merge pull request #646 from kubescape/fix_c_0256
Fix internet exposure rules
2 parents 28fbe92 + c5bef38 commit 8e83c4a

File tree

26 files changed

+1099
-20
lines changed

26 files changed

+1099
-20
lines changed

rules/exposure-to-internet-via-gateway-api/raw.rego

+46-7
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ deny[msga] {
1717
not is_exposed_service(svc)
1818

1919
wl := input[_]
20-
wl.metadata.namespace == svc.metadata.namespace
20+
is_same_namespace(wl.metadata, svc.metadata)
2121
spec_template_spec_patterns := {"Deployment", "ReplicaSet", "DaemonSet", "StatefulSet", "Pod", "Job", "CronJob"}
2222
spec_template_spec_patterns[wl.kind]
23-
wl_connected_to_service(wl, svc)
23+
pod := get_pod_spec(wl)["spec"]
24+
wl_connected_to_service(pod, svc)
2425

2526
result := svc_connected_to_httproute(svc, httproute)
2627

@@ -56,18 +57,56 @@ is_exposed_service(svc) {
5657
svc.spec.type == "LoadBalancer"
5758
}
5859

59-
wl_connected_to_service(wl, svc) {
60+
wl_connected_to_service(wl, svc) {
61+
62+
6063
count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector)
6164
}
6265

63-
wl_connected_to_service(wl, svc) {
64-
wl.spec.selector.matchLabels == svc.spec.selector
66+
67+
is_same_namespace(metadata1, metadata2) {
68+
metadata1.namespace == metadata2.namespace
6569
}
6670

67-
wl_connected_to_service(wl, svc) {
68-
count({x | svc.spec.selector[x] == wl.spec.template.metadata.labels[x]}) == count(svc.spec.selector)
71+
is_same_namespace(metadata1, metadata2) {
72+
not metadata1.namespace
73+
not metadata2.namespace
6974
}
7075

76+
is_same_namespace(metadata1, metadata2) {
77+
not metadata2.namespace
78+
metadata1.namespace == "default"
79+
}
80+
81+
is_same_namespace(metadata1, metadata2) {
82+
not metadata1.namespace
83+
metadata2.namespace == "default"
84+
}
85+
86+
87+
88+
# get_volume - get resource spec paths for {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
89+
get_pod_spec(resources) := result {
90+
resources_kinds := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
91+
resources_kinds[resources.kind]
92+
result = {"spec": resources.spec.template, "start_of_path": "spec.template."}
93+
}
94+
95+
# get_volume - get resource spec paths for "Pod"
96+
get_pod_spec(resources) := result {
97+
resources.kind == "Pod"
98+
result = {"spec": resources, "start_of_path": ""}
99+
}
100+
101+
# get_volume - get resource spec paths for "CronJob"
102+
get_pod_spec(resources) := result {
103+
resources.kind == "CronJob"
104+
result = {"spec": resources.spec.jobTemplate.spec.template.spec, "start_of_path": "spec.jobTemplate.spec.template.spec."}
105+
}
106+
107+
108+
109+
71110
svc_connected_to_httproute(svc, httproute) = result {
72111
rule := httproute.spec.rules[i]
73112
ref := rule.backendRefs[j]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
[
2+
{
3+
"alertMessage": "workload 'httpbin' is exposed through httproute 'httpbin'",
4+
"failedPaths": [],
5+
"fixPaths": [],
6+
"ruleStatus": "",
7+
"packagename": "armo_builtins",
8+
"alertScore": 7,
9+
"alertObject": {
10+
"k8sApiObjects": [
11+
{
12+
"apiVersion": "apps/v1",
13+
"kind": "Deployment",
14+
"metadata": {
15+
"name": "httpbin"
16+
}
17+
}
18+
]
19+
},
20+
"relatedObjects": [
21+
{
22+
"object": {
23+
"apiVersion": "gateway.networking.k8s.io/v1",
24+
"kind": "HTTPRoute",
25+
"metadata": {
26+
"creationTimestamp": "2024-02-04T19:06:03Z",
27+
"generation": 1,
28+
"labels": {
29+
"example": "httpbin-route"
30+
},
31+
"name": "httpbin",
32+
"namespace": "httpbin",
33+
"resourceVersion": "914",
34+
"uid": "fd820080-801d-4fa7-934a-e23abe8bf746"
35+
},
36+
"spec": {
37+
"hostnames": [
38+
"www.example.com"
39+
],
40+
"parentRefs": [
41+
{
42+
"group": "gateway.networking.k8s.io",
43+
"kind": "Gateway",
44+
"name": "http",
45+
"namespace": "gloo-system"
46+
}
47+
],
48+
"rules": [
49+
{
50+
"backendRefs": [
51+
{
52+
"group": "",
53+
"kind": "Service",
54+
"name": "httpbin",
55+
"port": 8000,
56+
"weight": 1
57+
}
58+
],
59+
"matches": [
60+
{
61+
"path": {
62+
"type": "PathPrefix",
63+
"value": "/"
64+
}
65+
}
66+
]
67+
}
68+
]
69+
},
70+
"status": {
71+
"parents": [
72+
{
73+
"conditions": [
74+
{
75+
"lastTransitionTime": "2024-02-04T19:06:03Z",
76+
"message": "",
77+
"observedGeneration": 1,
78+
"reason": "Accepted",
79+
"status": "True",
80+
"type": "Accepted"
81+
},
82+
{
83+
"lastTransitionTime": "2024-02-04T19:06:03Z",
84+
"message": "",
85+
"observedGeneration": 1,
86+
"reason": "ResolvedRefs",
87+
"status": "True",
88+
"type": "ResolvedRefs"
89+
}
90+
],
91+
"controllerName": "solo.io/gloo-gateway",
92+
"parentRef": {
93+
"group": "gateway.networking.k8s.io",
94+
"kind": "Gateway",
95+
"name": "http",
96+
"namespace": "gloo-system"
97+
}
98+
}
99+
]
100+
}
101+
},
102+
"failedPaths": [
103+
"spec.rules[0].backendRefs[0].name"
104+
],
105+
"reviewPaths": [
106+
"spec.rules[0].backendRefs[0].name"
107+
]
108+
},
109+
{
110+
"object": {
111+
"apiVersion": "v1",
112+
"kind": "Service",
113+
"metadata": {
114+
"creationTimestamp": "2024-02-04T19:05:12Z",
115+
"labels": {
116+
"app": "httpbin",
117+
"service": "httpbin"
118+
},
119+
"name": "httpbin",
120+
"namespace": "httpbin",
121+
"resourceVersion": "811",
122+
"uid": "c391feb7-54e5-41b2-869b-33166869f1b7"
123+
},
124+
"spec": {
125+
"clusterIP": "10.96.162.234",
126+
"clusterIPs": [
127+
"10.96.162.234"
128+
],
129+
"internalTrafficPolicy": "Cluster",
130+
"ipFamilies": [
131+
"IPv4"
132+
],
133+
"ipFamilyPolicy": "SingleStack",
134+
"ports": [
135+
{
136+
"name": "http",
137+
"port": 8000,
138+
"protocol": "TCP",
139+
"targetPort": 8080
140+
},
141+
{
142+
"name": "tcp",
143+
"port": 9000,
144+
"protocol": "TCP",
145+
"targetPort": 9000
146+
}
147+
],
148+
"selector": {
149+
"app": "httpbin"
150+
},
151+
"sessionAffinity": "None",
152+
"type": "ClusterIP"
153+
},
154+
"status": {
155+
"loadBalancer": {}
156+
}
157+
}
158+
}
159+
]
160+
}
161+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
annotations:
5+
deployment.kubernetes.io/revision: "1"
6+
creationTimestamp: "2024-02-04T19:05:12Z"
7+
generation: 1
8+
name: httpbin
9+
namespace: httpbin
10+
resourceVersion: "870"
11+
uid: 7462bb4c-b5a2-413e-80ee-c1baaf34aade
12+
spec:
13+
progressDeadlineSeconds: 600
14+
replicas: 1
15+
revisionHistoryLimit: 10
16+
selector:
17+
matchLabels:
18+
app: httpbin
19+
version: v1
20+
strategy:
21+
rollingUpdate:
22+
maxSurge: 25%
23+
maxUnavailable: 25%
24+
type: RollingUpdate
25+
template:
26+
metadata:
27+
labels:
28+
app: httpbin
29+
version: v1
30+
spec:
31+
containers:
32+
- args:
33+
- -port
34+
- "8080"
35+
- -max-duration
36+
- 600s
37+
command:
38+
- go-httpbin
39+
image: docker.io/mccutchen/go-httpbin:v2.6.0
40+
imagePullPolicy: IfNotPresent
41+
name: httpbin
42+
ports:
43+
- containerPort: 8080
44+
protocol: TCP
45+
resources: {}
46+
terminationMessagePath: /dev/termination-log
47+
terminationMessagePolicy: File
48+
- command:
49+
- tail
50+
- -f
51+
- /dev/null
52+
image: curlimages/curl:7.83.1
53+
imagePullPolicy: IfNotPresent
54+
name: curl
55+
resources:
56+
limits:
57+
cpu: 200m
58+
requests:
59+
cpu: 100m
60+
terminationMessagePath: /dev/termination-log
61+
terminationMessagePolicy: File
62+
- image: gcr.io/solo-public/docs/hey:0.1.4
63+
imagePullPolicy: IfNotPresent
64+
name: hey
65+
resources: {}
66+
terminationMessagePath: /dev/termination-log
67+
terminationMessagePolicy: File
68+
dnsPolicy: ClusterFirst
69+
restartPolicy: Always
70+
schedulerName: default-scheduler
71+
securityContext: {}
72+
serviceAccount: httpbin
73+
serviceAccountName: httpbin
74+
terminationGracePeriodSeconds: 30
75+
status:
76+
availableReplicas: 1
77+
conditions:
78+
- lastTransitionTime: "2024-02-04T19:05:32Z"
79+
lastUpdateTime: "2024-02-04T19:05:32Z"
80+
message: Deployment has minimum availability.
81+
reason: MinimumReplicasAvailable
82+
status: "True"
83+
type: Available
84+
- lastTransitionTime: "2024-02-04T19:05:12Z"
85+
lastUpdateTime: "2024-02-04T19:05:32Z"
86+
message: ReplicaSet "httpbin-f46cc8b9b" has successfully progressed.
87+
reason: NewReplicaSetAvailable
88+
status: "True"
89+
type: Progressing
90+
observedGeneration: 1
91+
readyReplicas: 1
92+
replicas: 1
93+
updatedReplicas: 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
apiVersion: gateway.networking.k8s.io/v1
2+
kind: HTTPRoute
3+
metadata:
4+
creationTimestamp: "2024-02-04T19:06:03Z"
5+
generation: 1
6+
labels:
7+
example: httpbin-route
8+
name: httpbin
9+
namespace: httpbin
10+
resourceVersion: "914"
11+
uid: fd820080-801d-4fa7-934a-e23abe8bf746
12+
spec:
13+
hostnames:
14+
- www.example.com
15+
parentRefs:
16+
- group: gateway.networking.k8s.io
17+
kind: Gateway
18+
name: http
19+
namespace: gloo-system
20+
rules:
21+
- backendRefs:
22+
- group: ""
23+
kind: Service
24+
name: httpbin
25+
port: 8000
26+
weight: 1
27+
matches:
28+
- path:
29+
type: PathPrefix
30+
value: /
31+
status:
32+
parents:
33+
- conditions:
34+
- lastTransitionTime: "2024-02-04T19:06:03Z"
35+
message: ""
36+
observedGeneration: 1
37+
reason: Accepted
38+
status: "True"
39+
type: Accepted
40+
- lastTransitionTime: "2024-02-04T19:06:03Z"
41+
message: ""
42+
observedGeneration: 1
43+
reason: ResolvedRefs
44+
status: "True"
45+
type: ResolvedRefs
46+
controllerName: solo.io/gloo-gateway
47+
parentRef:
48+
group: gateway.networking.k8s.io
49+
kind: Gateway
50+
name: http
51+
namespace: gloo-system

0 commit comments

Comments
 (0)