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

Escape terminal special characters in kubectl #112553

Merged
merged 2 commits into from Oct 30, 2022

Conversation

dgl
Copy link
Contributor

@dgl dgl commented Sep 19, 2022

Fixes #101695.

What type of PR is this?

/kind bug

What this PR does / why we need it:

Escapes terminal special characters in kubectl output. These can be used to confuse the user of kubectl, or potentially more serious attacks if their terminal emulator has a bug, as mentioned in the related issue.

Which issue(s) this PR fixes:

Fixes #101695

Special notes for your reviewer:

I've covered:

  • kubectl get (default table view)
  • kubectl get events -o custom-columns=message:".message"
  • kubectl describe
  • kubectl alpha events

Which I believe covers the original report along with the follow-up mentioned in #107617. Additionally I've confirmed that kubectl get -o json and kubectl get -o yaml perform their own escaping.

In addition to the original report I noticed that \r is allowed in various contexts, which can be used to replace the current line, and therefore still trick a user, so that is also escaped.

There are some cases which will not be covered, e.g. users using -o template=..., this is harder to fix as the user could be expecting to parse these outputs and ad-hoc human readable escaping may not be suitable. I believe these are less of a concern as the main commands are covered (we could consider detecting if the tty is a terminal or not, as done in some places in kubectl already, but then there are still issues, e.g. a user piping to grep).

Does this PR introduce a user-facing change?

kubectl now escapes terminal special characters in output. This fixes CVE-2021-25743.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/bug Categorizes issue or PR as related to a bug. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/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 Sep 19, 2022
@k8s-ci-robot
Copy link
Contributor

Welcome @dgl!

It looks like this is your first PR to kubernetes/kubernetes 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kubernetes has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Sep 19, 2022
@k8s-ci-robot
Copy link
Contributor

Hi @dgl. Thanks for your PR.

I'm waiting for a kubernetes 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. Regular contributors should join the org to skip this step.

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.

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.

@k8s-ci-robot k8s-ci-robot added area/kubectl sig/cli Categorizes an issue or PR as relevant to SIG CLI. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Sep 19, 2022
@dgl
Copy link
Contributor Author

dgl commented Sep 19, 2022

/sig cli
/sig security

@k8s-ci-robot k8s-ci-robot added the sig/security Categorizes an issue or PR as relevant to SIG Security. label Sep 19, 2022
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. label Sep 19, 2022
@pacoxu
Copy link
Member

pacoxu commented Sep 21, 2022

/ok-to-test
/priority important-longterm
/triage accepted

@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. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Sep 21, 2022
@pacoxu
Copy link
Member

pacoxu commented Sep 21, 2022

/assign @soltysh

Copy link
Member

@pacoxu pacoxu left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 9, 2022
if truncated {
fmt.Fprint(output, "...")
}
default:
fmt.Fprint(output, val)
WriteEscaped(output, fmt.Sprint(val))
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I'm not fully aware of the context of this change. Why we are fmt.Sprint(val)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's to get val into a string (i.e. via Stringer or the rules fmt uses), it made sense to me to make the new WriteEscaped take a string, rather than put the formatting over there, which might not match all caller's expectations.

e.Reason,
e.InvolvedObject.Kind, e.InvolvedObject.Name,
strings.TrimSpace(e.Message),
printers.EscapeTerminal(e.Type),
Copy link
Member

Choose a reason for hiding this comment

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

Aren't events only generated by kubernetes itself?, how user can generate events needed to be escaped?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See the kubectl create command mentioned in #101695 (comment) -- it's possible for a user (with enough permission against say a namespace) to do this, which could then be viewed by an admin or other user.

It might also be possible to get a \x1B into an error message that an operator or other component ends up putting into an event -- it doesn't make sense that every component should have to consider terminal escaping that is only relevant to kubectl (in the same way HTML escaping is usually done by the component that renders the HTML).

@@ -148,11 +149,13 @@ func (pw *prefixWriter) Write(level int, format string, a ...interface{}) {
for i := 0; i < level; i++ {
prefix += levelSpace
}
fmt.Fprintf(pw.out, prefix+format, a...)
output := fmt.Sprintf(prefix+format, a...)
Copy link
Member

Choose a reason for hiding this comment

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

fmt.Sprintf automatically escapes special characters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This formats it into a string, where WriteEscaped on the next line does that.

Copy link
Contributor

@soltysh soltysh left a comment

Choose a reason for hiding this comment

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

/lgtm
/approve

we still have annotations to cover as mentioned in the original issue, I doesn't look like this PR covers that bit, but since it's improving the current situation it's definitely worthy merge as is, and work on annotations in a follow

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dgl, pacoxu, soltysh

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

The pull request process is described here

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 k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 30, 2022
@soltysh
Copy link
Contributor

soltysh commented Oct 30, 2022

/labe tide/merge-method-squash

@soltysh
Copy link
Contributor

soltysh commented Oct 30, 2022

/label tide/merge-method-squash

@k8s-ci-robot k8s-ci-robot added the tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. label Oct 30, 2022
@pacoxu
Copy link
Member

pacoxu commented Oct 30, 2022

/retest
for a flake Test_Run_OneVolumeDetachFailNodeWithReadWriteOnce

@k8s-ci-robot k8s-ci-robot merged commit dad0e93 into kubernetes:master Oct 30, 2022
@k8s-ci-robot k8s-ci-robot added this to the v1.26 milestone Oct 30, 2022
@buckaroogeek
Copy link

Will this fix be available in 1.25 and 1.24? I tried to find relevant guidance in the Kubernetes security documentation but did not see anything. thanks

jaehnri pushed a commit to jaehnri/kubernetes that referenced this pull request Jan 3, 2023
* Escape terminal special characters in kubectl

* Add escaping for kubectl alpha events
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/kubectl cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/security Categorizes an issue or PR as relevant to SIG Security. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ANSI escape characters in kubectl output are not being filtered
6 participants