Uh oh!
There was an error while loading. Please reload this page.
Add validation to warn about insecure SecurityContext defaults - #13399
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: evankanderson The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
evankanderson
commented
Oct 16, 2022
I need to add an |
…default SecurityContexts dozens of times
evankanderson
commented
Oct 16, 2022
@mattmoor -- it looks like "warning level errors" are translating into |
mattmoor
commented
Oct 16, 2022
Ah no, that's because this was never taught about warnings: |
mattmoor
commented
Oct 16, 2022
tl;dr we added reactors to simulate validation webhooks in our table tests by calling |
evankanderson
commented
Oct 16, 2022
Hah, I can do that, then. I didn't realize that this wasn't going through an actual apiserver in the test. |
mattmoor
commented
Oct 16, 2022
I definitely didn't want to bring in an API server as a requirement for unit testing, that seems rough 😅 |
…ecure-defaults-for-3-years
…ecure-defaults-for-3-years
Codecov ReportBase: 86.43% // Head: 86.17% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@## main #13399 +/- ##
==========================================
- Coverage 86.43% 86.17% -0.26%
==========================================
Files 196 197 +1 Lines 14600 14723 +123 ==========================================
+ Hits 12619 12688 +69 - Misses 1680 1733 +53 - Partials 301 302 +1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
…://github.com/evankanderson/serving into warning-warning-insecure-defaults-for-3-years
evankanderson
commented
Dec 30, 2022
/retest |
psschwei
left a comment
There was a problem hiding this comment.
other than a nit on the comment, LGTM
| // warnDefaultContainerSecurityContext warns about Kubernetes default | ||
| // SecurityContext values which are insecure (i.e. the "restricted" profile | ||
| // forbids these values). Because securityContext values may also be set at | ||
| // the Pod level, the container-level settings need to be considered alongside | ||
| // the Pod-level settings. |
There was a problem hiding this comment.
nit: the release note is a little clearer in that the warning will sound when these values are unset. would be helpful to include that detail in the comment here, maybe something like:
| // warnDefaultContainerSecurityContext warns about Kubernetes default | |
| // SecurityContext values which are insecure (i.e. the "restricted" profile | |
| // forbids these values). Because securityContext values may also be set at | |
| // the Pod level, the container-level settings need to be considered alongside | |
| // the Pod-level settings. | |
| // warnDefaultContainerSecurityContext warns about Kubernetes default | |
| // SecurityContext values which are unset and thus insecure (i.e. the "restricted" profile | |
| // forbids these values). Because securityContext values may also be set at | |
| // the Pod level, the container-level settings need to be considered alongside | |
| // the Pod-level settings. |
There was a problem hiding this comment.
Done (and rewrapped, just 'cuz)
| for i := range ps.Containers { | ||
| errs = errs.Also( | ||
| warnDefaultContainerSecurityContext(ctx, ps.SecurityContext, ps.Containers[i].SecurityContext). | ||
| ViaFieldIndex("containers", 1).ViaField("securityContext")) |
There was a problem hiding this comment.
I think 1 should be i
| ViaFieldIndex("containers", 1).ViaField("securityContext")) | |
| ViaFieldIndex("containers", i).ViaField("securityContext")) |
There was a problem hiding this comment.
Ugh, I think I might have let AutoPilot write these... that's a crazy mistake.
Thanks!
There was a problem hiding this comment.
ViaField and ViaFieldIndex were backwards here, too, which I noticed in the test output when I was fixing the [1] in the tests.
| for i := range ps.InitContainers { | ||
| errs = errs.Also( | ||
| warnDefaultContainerSecurityContext(ctx, ps.SecurityContext, ps.InitContainers[i].SecurityContext). | ||
| ViaFieldIndex("initContainers", 1).ViaField("securityContext")) |
There was a problem hiding this comment.
Likewise 1 should be i
| ViaFieldIndex("initContainers", 1).ViaField("securityContext")) | |
| ViaFieldIndex("initContainers", i).ViaField("securityContext")) |
| ps corev1.PodSpec | ||
| cfgOpts []configOption | ||
| want *apis.FieldError | ||
| errLevel apis.DiagnosticLevel |
There was a problem hiding this comment.
question: is the default value (0) == apis.ErrorLevel
looks like it is - https://github.com/knative/pkg/blob/247510c00e9dbb7f5a23b76e8ab76654de173a04/apis/field_error.go#L38
There was a problem hiding this comment.
I think it would be more clear in the tests that don't assert warnings to just filter in the t.Run instead of adding the additional option to the test case
got = got.Filter(apis.ErrorLevel)
There was a problem hiding this comment.
Yes, the default value is error for compatibility with all the existing code.
I think I was trying to be consistent here, but I can roll all these back if you prefer.
| errs = errs.Also(insecureDefault("capabilities")) | ||
| } else { | ||
| if sc.Capabilities.Drop == nil { | ||
| errs = errs.Also(insecureDefault("capabilities.drop")) |
There was a problem hiding this comment.
You might want to add a warning that all needs to be ALL - or error out on this even
Knative made this mistake and it was only recently fixed - #13327
There was a problem hiding this comment.
Added a warning if arg 0 is "all", I think that should be sufficient for now.
evankanderson
commented
Jan 20, 2023
(Still rolling back the validation_test changes, but wanted to get other bits pushed.) |
evankanderson
commented
Jan 20, 2023
Okay, this should be ready for another review. |
dprotaso
commented
Jan 20, 2023
/lgtm |
Fixes#13398
It would be nice if the Kubernetes defaults for SecurityContext and PodSecurityContext followed the
Pod Security Standards
restrictedprofile, whichis "following current Pod hardening best practices", but they do not, presumably for historical reasons.
Since all the SecurityContext values which have insecure defaults can distinguish between "default value" and "declared insecure"
(either via pointer or empty-string vs dangerous string), it seems reasonable to warn about these defaults in Knative, and
default them to "safe" values in the future, since we've knowingly restricted our set of workloads to those that should be safer.
Proposed Changes
Explicitly setting values to their (insecure) defaults will disable the warning. This is intentional, we only want to alert people who
may not know the default values have higher privilege than necessary.
Release Note