Skip to content

Fix PvCSI service account regex security vulnerability (SUP-VULN-0009)#4024

Open
anuj087 wants to merge 1 commit into
kubernetes-sigs:masterfrom
anuj087:fix_pvcsi_service_account_regex_vulnerability
Open

Fix PvCSI service account regex security vulnerability (SUP-VULN-0009)#4024
anuj087 wants to merge 1 commit into
kubernetes-sigs:masterfrom
anuj087:fix_pvcsi_service_account_regex_vulnerability

Conversation

@anuj087
Copy link
Copy Markdown
Contributor

@anuj087 anuj087 commented May 7, 2026

The original regex ^system:serviceaccount.*-pvcsi$ was vulnerable to colon injection attacks. A malicious user could create a service account named 'evil-pvcsi' in their namespace and bypass webhook security checks by having their username appear as:
system:serviceaccount:malicious-namespace:evil-pvcsi

This would match the regex and be treated as a trusted PvCSI service account.

Fixed by replacing the overly broad .* pattern with matching the username with the service account name which is "vsphereClusterName"-pvcsi

This prevents colon injection while maintaining compatibility with legitimate PvCSI service accounts.

Added comprehensive test coverage to prevent regression.

Security Impact: MEDIUM - Prevents authentication bypass for CnsFileAccessConfig operations.

Testing done: Both VKS and WCP precheckins are passed
https://jenkins-vcf-csifvt.devops.broadcom.net/view/instapp/job/vks-instapp-e2e-pre-checkin/1207/
https://jenkins-vcf-csifvt.devops.broadcom.net/job/wcp-instapp-e2e-pre-checkin/1621/

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 7, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label May 7, 2026
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: anuj087
Once this PR has been reviewed and has the lgtm label, please assign deepakkinni for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Hi @anuj087. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 7, 2026
@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from 909d1c8 to c111ba8 Compare May 7, 2026 06:54
@skogta
Copy link
Copy Markdown
Contributor

skogta commented May 7, 2026

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 7, 2026
@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from c111ba8 to 4321bd1 Compare May 7, 2026 07:28
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels May 7, 2026
@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from 4321bd1 to 04e70d3 Compare May 8, 2026 11:27
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels May 8, 2026
@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from 04e70d3 to 016ae28 Compare May 8, 2026 11:28
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels May 8, 2026
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-WCP Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1471

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1471

@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch 2 times, most recently from 88dd9e5 to 2a77623 Compare May 14, 2026 06:52
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-WCP Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1517

@deepakkinni
Copy link
Copy Markdown
Collaborator

SUCCESS --- Jenkins Build #1517

@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from 7516465 to f65d7b4 Compare May 18, 2026 07:06
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1226

@deepakkinni
Copy link
Copy Markdown
Collaborator

SUCCESS --- Jenkins Build #1226

@k8s-ci-robot k8s-ci-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 3, 2026
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1229

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1229

@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1225

@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1231

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1225

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1231

@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 3, 2026
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1233

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1233

@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-WCP Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1619

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1619

@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1234

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1234

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jun 3, 2026
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-WCP Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1621

@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1235

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

k8s-ci-robot commented Jun 3, 2026

@anuj087: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-vsphere-csi-driver-verify-markdown 04e70d3 link true /test pull-vsphere-csi-driver-verify-markdown
pull-vsphere-csi-driver-verify-shell 04e70d3 link true /test pull-vsphere-csi-driver-verify-shell

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1235

@deepakkinni
Copy link
Copy Markdown
Collaborator

SUCCESS --- Jenkins Build #1621

The original regex ^system:serviceaccount.*-pvcsi$ was vulnerable to
colon injection attacks. A malicious user could create a service account
named 'evil-pvcsi' in their namespace and bypass webhook security checks
by having their username appear as:
system:serviceaccount:malicious-namespace:evil-pvcsi

This would match the regex and be treated as a trusted PvCSI service account.

Fixed by replacing the overly broad .* pattern with a more restrictive
regex that:
1. Uses [^:]+ for namespace (no colons allowed)
2. Explicitly allows legitimate service accounts:
   - vsphere-csi-controller
   - vsphere-csi-node
   - pvcsi
   - Any service account ending with -pvcsi (but no colons in name)

New regex: ^system:serviceaccount:[^:]+:(vsphere-csi-controller|vsphere-csi-node|pvcsi|[^:]*-pvcsi)$

This prevents colon injection while maintaining compatibility with
legitimate PvCSI service accounts.

Added comprehensive test coverage to prevent regression.

Security Impact: MEDIUM - Prevents authentication bypass for
CnsFileAccessConfig operations.

Signed-off-by: ab002488
@anuj087 anuj087 force-pushed the fix_pvcsi_service_account_regex_vulnerability branch from c9108d6 to f104084 Compare June 4, 2026 09:50
@deepakkinni
Copy link
Copy Markdown
Collaborator

Triggering CSI-TKG Pre-checkin Pipeline for this PR... Job takes approximately an hour to complete
Jenkins Build #1244

@deepakkinni
Copy link
Copy Markdown
Collaborator

FAILED --- Jenkins Build #1244

// Extract expected vsphere cluster name from service account name
// serviceAccountName format: "{vsphere-cluster-name}-pvcsi"
if !strings.HasSuffix(serviceAccountName, "-pvcsi") {
log.Infof("Service account '%s' does not follow cluster pattern (missing -pvcsi suffix)", serviceAccountName)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have this validation twice?

return false, nil
}

if errors.IsForbidden(err) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this check required? Why can't we club it with the rest of the other errors?

log.Infof("Parsed service account parts: %v (count: %d)", parts, len(parts))

if len(parts) != 2 {
log.Infof("Invalid service account format - expected 2 parts, got %d, returning false", len(parts))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errorf

// For any namespace, check if service account follows guest cluster PvCSI pattern
// Guest cluster PvCSI service accounts follow the pattern: {cluster-name}-pvcsi
if strings.HasSuffix(serviceAccountName, "-pvcsi") {
log.Infof("Service account ends with -pvcsi, validating as guest cluster PvCSI account")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errof


func validatePvCSIServiceAccount(username string) (bool, error) {
pvcCsiServiceAccountRegex, err := regexp.Compile(PvCsiServiceAccountregex)
ctx := context.TODO()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the existing ctx

vsphereCluster := &unstructured.Unstructured{}
vsphereCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: "vmware.infrastructure.cluster.x-k8s.io",
Version: "v1beta2", // Use the version we saw in kubectl api-resources
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikhilbarge is this the correct version to use?


// Allowed users are :
// 1. PVCSI service account
// 1. PVCSI service account (checked above using new validation logic)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check no longer validates if it is a PVCSI service account. We already return at line 242. So this comment is outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants