gatekeeper-library
gatekeeper-library copied to clipboard
Cve 2020 8554
This policy would deny all usage of LoadBalancers IPs, which may be a bit too restrictive. Consider adding a whitelist option through an allowedUsers parameter. Something similar is done in the externalIP constraint template to whitelist IPs (allowedIPs).
The system service account that normally updates Load Balancer IPs through services/status requests is system:serviceaccount:kube-system:service-controller
, it should probably be included in the allowedUsers whitelist, if you choose to implement it.
This policy would deny all usage of LoadBalancers IPs, which may be a bit too restrictive. Consider adding a whitelist option through an allowedUsers parameter. Something similar is done in the externalIP constraint template to whitelist IPs (allowedIPs).
The system service account that normally updates Load Balancer IPs through services/status requests is
system:serviceaccount:kube-system:service-controller
, it should probably be included in the allowedUsers whitelist, if you choose to implement it.
I checked the following scenario and it works fine:
- Create clusterip service
- Update the service type to loadbalancer
After few seconds a public ip was assigned to the service, which means the policy has no impact on the work of the service controller. Please let me know if we have more scenarios to test.
@AbirHamzi The service controller is able to assign a Load Balancer IP because template.yaml misses the first assignment of a Load Balancer IP. You can verify that by patching the status of a LoadBalancer service just after creating it, before the service controller managed to assign it a Load Balancer IP.
To prevent this bypass, replace the following line in template.yaml:
request.oldObject.status.loadBalancer.ingress != request.object.status.loadBalancer.ingress
With:
newLoadBalancerIPs := {ips | ips := request.object.status.loadBalancer.ingress[_].ip} - {oldips | oldips := input.review.oldObject.status.loadBalancer.ingress[_].ip}
count(newLoadBalancerIPs) > 0
@AbirHamzi The service controller is able to assign a Load Balancer IP because template.yaml misses the first assignment of a Load Balancer IP. You can verify that by patching the status of a LoadBalancer service just after creating it, before the service controller managed to assign it a Load Balancer IP.
To prevent this bypass, replace the following line in template.yaml:
request.oldObject.status.loadBalancer.ingress != request.object.status.loadBalancer.ingress
With:
newLoadBalancerIPs := {ips | ips := request.object.status.loadBalancer.ingress[_].ip} - {oldips | oldips := input.review.oldObject.status.loadBalancer.ingress[_].ip} count(newLoadBalancerIPs) > 0
Yes indeed you are right. I'm working on that, thank you for your feedback.
Thank you for the submission!
Is this the same CVE that this template was meant to address?
https://github.com/open-policy-agent/gatekeeper-library/pull/39
Referenced in this k8s issue
Thank you for the submission!
Is this the same CVE that this template was meant to address?
#39
Referenced in this k8s issue
@maxsmythe yes it's the same CVE, but restricting service externalIPs/loadbalancerIPs to an allowlist is not enough because the hacker still can patch the service status and intercept the traffic.
Is this PR still needed now we have https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/general/externalip?