Live data from Hacker News

Helm local code execution via a malicious chart

github.com

81–90 of 99 posts

Re: Helm local code execution via a malicious chart

#81

If we're being honest, YAML is one of the dumbest ideas of the last 20 years to have proliferated. How we got from XML to here I cannot comprehend. This is not the first RCE involving YAML and it won't be the last.

Why we settled on a file format that relies on invisible characters I'll never know.

Exactly how I feel about Python!

Re: Helm local code execution via a malicious chart

#82
post #79

Earlier quoted context omitted.

The NO case is not valid JSON. So that leaves scientific notation.

The point is that "going right ahead and write your .yml files in JSON" is not valid. You'd have to restrict yourself to a subset of JSON to not get different semantics.

If you configure the parser to treat it as YAML 1.2 then you don't need to restrict yourself to a subset.

Re: Helm local code execution via a malicious chart

#83
post #69
post #68

Earlier quoted context omitted.

When you do a helm pull and download a chart from a repo, I believe it's a tar-ball. So if you have a workflow where you install charts from the filesystem you could be impacted. I've done that in the past.

I can only repeat the assertion: if you have a victim pulling and installing untrusted tarballs , there is no security boundary being crossed. It doesn't matter whether it's "from a repo". If you can't trust the repo it can feed you whatever it wants.

You're not installing the untrusted tarball; helm is merely supposed to be extracting it, and then rendering the templates contained within.

(Those templates, once rendered, might then refer to pods, etc. that might be put into a k8s cluster (or perhaps we merely render then YAML, and never `apply` it), and in that sense, one might imagine that that is an install, but that's not the security boundary being crossed here; this would presumably result in execution on the host running helm, which would definitely be surprising.)

Re: Helm local code execution via a malicious chart

#84
post #58

Helm is an abomination, as the whole idea of using a text template engine to generate YAML is. And this vulnerability adds insult to injury ;) Sorry, just can't really recover from trauma of counting spaces and messing up newlines, etc. when writing Helm templates. You know, Lisp "sucks" because "you need to count parenthesis" (you actually don't), yet Helm is a widely accepted technology where you need to count spac…

This isn't a uniquely helm thing though, they mostly use modified go templating. Lots of other things do this with yaml as well.

… and I think I'd argue that the parent's argument against the tooling would apply equally as well to those "other things", too.

The alternative here is something that manipulates the data structure directly. E.g., it might permit me to say:

  my_config_map.data["key"] = some_string_value
(This is in some pseudo-imperative language, vs. the parent's Lisp, but that distinction isn't particular relevant to the core of their argument, I think.)

And then at the end, the thing itself takes care of converting the resulting objects to YAML, thus preventing me from inadvertently turning what is meant to be a string into something like an accidental YAML-injection that results in terrible errors because I miscounted the number of spaces to indent something.

Re: Helm local code execution via a malicious chart

#85
post #6

What is the attack scenario here? Where are the security boundaries? How does the attacker gets their repository with a symlink in it to the victim? Is Helm typically run as a privileged user? How would this work? And why doesn't the vulnerability description give answers to these questions?

> What is the attack scenario here?

Given the details in the article, I think even something as simple a templating a chart from a repository might be vuln., but it likely depends on a lot of exact specifics.

> Where are the security boundaries?

I expect templating does not result in LCE.

> How does the attacker gets their repository with a symlink in it to the victim?

The attacker owns the repository. They can serve whatever maliciousness in it they want. But should templating a malicious chart result in LCE?

> Is Helm typically run as a privileged user?

Enough so, yes, because the rendered result is often pushed to a k8s cluster. "Privileged" here might not be "root", but it might be "this user has k8s API access".

Imagine, e.g., that the attacker's LCE here might be "push ~/.kube to attacker".

> And why doesn't the vulnerability description give answers to these questions?

Familiarity with the tools involved is an normal assumption.

Re: Helm local code execution via a malicious chart

#86
post #79

Earlier quoted context omitted.

The point is that "going right ahead and write your .yml files in JSON" is not valid. You'd have to restrict yourself to a subset of JSON to not get different semantics.

If you configure the parser to treat it as YAML 1.2 then you don't need to restrict yourself to a subset.

This is a valid JSON value:

  "\ud83d\udca9"
Python's "PyYAML" package will not decode this to the same result as a JSON decoding.

Rust's `serde_yaml` will fail on this.

I don't know about other parsers, but I'd be curious to.

The standard itself isn't well written here, IMO.

> The content of a scalar node is an opaque datum that can be presented as a series of zero or more Unicode characters.

The example here is a "quoted scalar", which can contain the escapes you see. Those escapes represent "Unicode characters", specifically,

> Escaped 16-bit Unicode character.

But "Unicode characters" is never defined by YAML.

Most implementation seem to treat them as Unicode code points, and so thus the resulting string type in almost all cases in something like [UnicodeCodePoint]; in Rust, that means no unpaired surrogates, or we can't convert it to a Rust `String`, which is roughly speaking `[USV]`. In Python, that's workable, since that's Python's `str` datatype, but that means no surrogate decoding occurs.

The grammar also further implies that it's [UnicodeCodePoint] and not [USV], and the prose never restricts unpaired surrogates. (The JSON standard strongly implies the UTF-16 decoding should happen on escaped values, though it too waffles around unpaired surrogates. Whether unpaired surrogates are accepted is variable in JSON.)

But compare with a JSON string: a JSON string decodes to a something like a [USV], so surrogate pairs are decoded to their corresponding USV.

Re: Helm local code execution via a malicious chart

#87
post #58

Helm is an abomination, as the whole idea of using a text template engine to generate YAML is. And this vulnerability adds insult to injury ;) Sorry, just can't really recover from trauma of counting spaces and messing up newlines, etc. when writing Helm templates. You know, Lisp "sucks" because "you need to count parenthesis" (you actually don't), yet Helm is a widely accepted technology where you need to count spac…

I'm a dev that jumped to devops and one of my pet peeves will always be the lengths devops engineers go to avoid using a real programming language. Instead of interacting with all these APIs through python, ruby, lua, go, whatever they would rather build hodgepodge systems in bash, coreutils, curl (or wget. or both!) and jq (which is the worst). Or in the case of helm, just creating a half yaml/half Go SDK for genera…

You'll often find that if you write ops scripts in, say Python, it's largely calling external commands.

When that's the case, bash if often the better choice, especially if you know it well. It has an excellent REPL, is easy to trace and is already installed everywhere.

Re: Helm local code execution via a malicious chart

#88
post #58

Helm is an abomination, as the whole idea of using a text template engine to generate YAML is. And this vulnerability adds insult to injury ;) Sorry, just can't really recover from trauma of counting spaces and messing up newlines, etc. when writing Helm templates. You know, Lisp "sucks" because "you need to count parenthesis" (you actually don't), yet Helm is a widely accepted technology where you need to count spac…

Something like kustomize was a better approach, where resources are templates semantically.

Though it's lacking in several ways, like good destroy functionality.

Re: Helm local code execution via a malicious chart

#89
post #69

Earlier quoted context omitted.

I can only repeat the assertion: if you have a victim pulling and installing untrusted tarballs , there is no security boundary being crossed. It doesn't matter whether it's "from a repo". If you can't trust the repo it can feed you whatever it wants.

You're not installing the untrusted tarball; helm is merely supposed to be extracting it, and then rendering the templates contained within. (Those templates, once rendered, might then refer to pods, etc. that might be put into a k8s cluster (or perhaps we merely render then YAML, and never `apply` it), and in that sense, one might imagine that that is an install, but that's not the security boundary being crossed he…

You're quibbling over the meaning of "install" but apparently conceding the part about untrusted? OK, fair enough. I still argue that any process involving the extraction and (ahem) "rendering of contained templates" from untrusted sources is broken in ways a fix for this particular symlink issue isn't going to address.

Re: Helm local code execution via a malicious chart

#90
post #58

Helm is an abomination, as the whole idea of using a text template engine to generate YAML is. And this vulnerability adds insult to injury ;) Sorry, just can't really recover from trauma of counting spaces and messing up newlines, etc. when writing Helm templates. You know, Lisp "sucks" because "you need to count parenthesis" (you actually don't), yet Helm is a widely accepted technology where you need to count spac…

I'm a dev that jumped to devops and one of my pet peeves will always be the lengths devops engineers go to avoid using a real programming language. Instead of interacting with all these APIs through python, ruby, lua, go, whatever they would rather build hodgepodge systems in bash, coreutils, curl (or wget. or both!) and jq (which is the worst). Or in the case of helm, just creating a half yaml/half Go SDK for genera…

> the lengths devops engineers go to avoid using a real programming language

OK, but, you know... those tools were created by literal devs. Not in yaml, in a "real language"! So apparently devs thought they needed that.

The argument should be towards all people - we love creating new abstractions and "simplify things", but we suck at honest evaluation of the impact of our creations.

Still: I absolutely hate Helm templating and think that the very existence of "helpers" (even in a default chart!) is an abomination.

Post reply on HN