Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forbidden message may include RBAC information #124406

Open
rtheis opened this issue Apr 19, 2024 · 8 comments
Open

forbidden message may include RBAC information #124406

rtheis opened this issue Apr 19, 2024 · 8 comments
Labels
kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. sig/auth Categorizes an issue or PR as relevant to SIG Auth.

Comments

@rtheis
Copy link

rtheis commented Apr 19, 2024

What happened?

Kubernetes API server may include extra RBAC information on forbidden error messages. An authenticated user could gain unexpected knowledge of possible Kubernetes RBAC configuration problems.

What did you expect to happen?

Error message does not include RBAC information.

How can we reproduce it (as minimally and precisely as possible)?

Test 1

kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
kubectl auth can-i create pods -n kube-system --as=system:anonymous
curl -k https://KUBERNETES_API_SERVER_HOST:KUBERNETES_API_SERVER_PORT/foo
kubectl apply -f - <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: test
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:unauthenticated
EOF
kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
kubectl auth can-i create pods -n kube-system --as=system:anonymous
curl -k https://KUBERNETES_API_SERVER_HOST:KUBERNETES_API_SERVER_PORT/foo

Example Results for Test 1:

vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
no
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:anonymous
Error from server (Forbidden): selfsubjectaccessreviews.authorization.k8s.io is forbidden: User "system:anonymous" cannot create resource "selfsubjectaccessreviews" in API group "authorization.k8s.io" at the cluster scope
vagrant@verify-cluster:~$ curl -k https://c105.containers.test.cloud.ibm.com:31573/foo
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/foo\"",
  "reason": "Forbidden",
  "details": {},
  "code": 403
}vagrant@verify-cluster:~$ kubectl apply -f - <<EOF
> kind: ClusterRoleBinding
> apiVersion: rbac.authorization.k8s.io/v1
> metadata:
>   name: test
> roleRef:
>   apiGroup: rbac.authorization.k8s.io
>   kind: ClusterRole
>   name: test
> subjects:
> - apiGroup: rbac.authorization.k8s.io
>   kind: Group
>   name: system:unauthenticated
> EOF
clusterrolebinding.rbac.authorization.k8s.io/test created
vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
no
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:anonymous
Error from server (Forbidden): selfsubjectaccessreviews.authorization.k8s.io is forbidden: User "system:anonymous" cannot create resource "selfsubjectaccessreviews" in API group "authorization.k8s.io" at the cluster scope: RBAC: clusterrole.rbac.authorization.k8s.io "test" not found
vagrant@verify-cluster:~$ curl -k https://c105.containers.test.cloud.ibm.com:31573/foo
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/foo\": RBAC: clusterrole.rbac.authorization.k8s.io \"test\" not found",
  "reason": "Forbidden",
  "details": {},
  "code": 403
}vagrant@verify-cluster:~$ 

Test 2 with Results: Kubernetes API server updated with --anonymous-auth=false.

vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
no
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:anonymous
Error from server (Forbidden): selfsubjectaccessreviews.authorization.k8s.io is forbidden: User "system:anonymous" cannot create resource "selfsubjectaccessreviews" in API group "authorization.k8s.io" at the cluster scope
vagrant@verify-cluster:~$ curl -k https://c105.containers.test.cloud.ibm.com:31573/foo
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ kubectl apply -f - <<EOF
> kind: ClusterRoleBinding
> apiVersion: rbac.authorization.k8s.io/v1
> metadata:
>   name: test
> roleRef:
>   apiGroup: rbac.authorization.k8s.io
>   kind: ClusterRole
>   name: test
> subjects:
> - apiGroup: rbac.authorization.k8s.io
>   kind: Group
>   name: system:serviceaccounts
> - apiGroup: rbac.authorization.k8s.io
>   kind: Group
>   name: system:unauthenticated
> EOF
clusterrolebinding.rbac.authorization.k8s.io/test created
vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ 
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:serviceaccount:default:default
no - RBAC: clusterrole.rbac.authorization.k8s.io "test" not found
vagrant@verify-cluster:~$ kubectl auth can-i create pods -n kube-system --as=system:anonymous
Error from server (Forbidden): selfsubjectaccessreviews.authorization.k8s.io is forbidden: User "system:anonymous" cannot create resource "selfsubjectaccessreviews" in API group "authorization.k8s.io" at the cluster scope: RBAC: clusterrole.rbac.authorization.k8s.io "test" not found
vagrant@verify-cluster:~$ curl -k https://c105.containers.test.cloud.ibm.com:31573/foo
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}vagrant@verify-cluster:~$

Anything else we need to know?

This issue was originally filed at https://hackerone.com but was closed. I was told to open an issue here.

Kubernetes version

Kubernetes versions 1.26.15 and 1.30.0-rc.1 were tested, but other versions likely impacted. Test was conducted against Kubernetes clusters deployed using IBM Cloud Kubernetes Service.

Cloud provider

N/A

OS version

N/A

Install tools

IBM Cloud Kubernetes Service

Container runtime (CRI) and version (if applicable)

N/A

Related plugins (CNI, CSI, ...) and versions (if applicable)

N/A
@rtheis rtheis added the kind/bug Categorizes issue or PR as related to a bug. label Apr 19, 2024
@k8s-ci-robot k8s-ci-robot added needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Apr 19, 2024
@k8s-ci-robot
Copy link
Contributor

This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

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/test-infra repository.

@rtheis
Copy link
Author

rtheis commented Apr 19, 2024

/sig-auth

@rtheis
Copy link
Author

rtheis commented Apr 19, 2024

/sig auth

@k8s-ci-robot k8s-ci-robot added sig/auth Categorizes an issue or PR as relevant to SIG Auth. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Apr 19, 2024
@sftim
Copy link
Contributor

sftim commented Apr 19, 2024

As a mitigation: don't misconfigure your Kubernetes cluster; specifically, don't bind unauthenticated users to a missing ClusterRole.

@enj
Copy link
Member

enj commented Apr 22, 2024

From the slack thread:

image

@enj
Copy link
Member

enj commented Apr 22, 2024

I will leave this open for a while to get more community feedback, but I don't see us making any changes to address this.

@rtheis
Copy link
Author

rtheis commented Apr 23, 2024

My general concern is that there may be additional error messages leaked that may be of more value. I agree that this specific example is not very impactful.

@enj
Copy link
Member

enj commented Apr 23, 2024

My general concern is that there may be additional error messages leaked that may be of more value. I agree that this specific example is not very impactful.

Any error comes from the visitor passed to this method:

func (r *DefaultRuleResolver) VisitRulesFor(user user.Info, namespace string, visitor func(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool) {
if clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings(); err != nil {
if !visitor(nil, nil, err) {
return
}
} else {
sourceDescriber := &clusterRoleBindingDescriber{}
for _, clusterRoleBinding := range clusterRoleBindings {
subjectIndex, applies := appliesTo(user, clusterRoleBinding.Subjects, "")
if !applies {
continue
}
rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
if err != nil {
if !visitor(nil, nil, err) {
return
}
continue
}
sourceDescriber.binding = clusterRoleBinding
sourceDescriber.subject = &clusterRoleBinding.Subjects[subjectIndex]
for i := range rules {
if !visitor(sourceDescriber, &rules[i], nil) {
return
}
}
}
}
if len(namespace) > 0 {
if roleBindings, err := r.roleBindingLister.ListRoleBindings(namespace); err != nil {
if !visitor(nil, nil, err) {
return
}
} else {
sourceDescriber := &roleBindingDescriber{}
for _, roleBinding := range roleBindings {
subjectIndex, applies := appliesTo(user, roleBinding.Subjects, namespace)
if !applies {
continue
}
rules, err := r.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
if err != nil {
if !visitor(nil, nil, err) {
return
}
continue
}
sourceDescriber.binding = roleBinding
sourceDescriber.subject = &roleBinding.Subjects[subjectIndex]
for i := range rules {
if !visitor(sourceDescriber, &rules[i], nil) {
return
}
}
}
}
}
}

They all boil down to "failed to get/list one of the 4 RBAC resources."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. sig/auth Categorizes an issue or PR as relevant to SIG Auth.
Projects
Status: Pre-triage follow-up
Development

No branches or pull requests

4 participants