📑
K8s の脆弱性 CVE-2021-25735 について
脆弱性
CVE-2021-25735 が公開されました。Validating Admission Webhook
にて validation をすり抜けてしまう脆弱性です。
具体例
早速具体例を見ていきましょう。この例は Node を UPDATE する際に、 label のチェックを行うValidating Admission Webhook
です。既存の label editAllowed
がtrue
であれば UPDATE を許可し、それ以外であれば拒否します。
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();
});
}
では下記コマンドで実際に Node を変更してみましょう。
$ kubectl edit nodes nodename
...
labels:
editAllowed: "false"
...
ここにdummy: dummy
というラベルを追記します。
labels:
dummy: dummy
editAllowed: "false"
当然、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.
ここで、editAllowed
もtrue
に変更した場合はどうでしょうか。
labels:
dummy: dummy
editAllowed: "true"
こうすることでValidating Admission Webhook
のチェックがOKとなりdummy: dummy
ラベルを追加できてしまうのです。
原因
kube-apiserver
はrequest.object
とrequest.oldObject
というオブジェクトをValidating Admission Webhook
に渡します。request.object
には新しい設定が入り、request.oldObject
には古い設定が入りますが、request.object
がrequest.oldObject
の一部を上書きしてしまう不具合があるため、このようなことが起こります。
影響範囲
これまで見てきたように、
- Node に対して
Validating Admission Webhook
を使用している - 既存データを条件とした
Validating Admission Webhook
を使用している
という条件の場合に当脆弱性の影響を受けます。
また、下記バージョンのkube-apiserver
が影響を受けます。
- kube-apiserver v1.20.0 - v1.20.5
- kube-apiserver v1.19.0 - v1.19.9
- kube-apiserver <= v1.18.17
Discussion