dylanaraps / pure-sh-bible

📖 A collection of pure POSIX sh alternatives to external processes.
MIT License
6.45k stars 281 forks source link

Dynamic variable naming magic #16

Closed FriendlyNeighborhoodShane closed 4 years ago

FriendlyNeighborhoodShane commented 4 years ago

@dylanaraps I'm really sorry, I forgot an extra backslash for escaping the escape in \n (due to the 2nd interpretation)

I was testing it with echo ':P

Crestwave commented 4 years ago

I'm a bit surprised this was merged without any commentary; note that eval is evil. It can be useful in some cases, such as the second use, but it must be used with caution (as demonstrated by that mistake). The first usage also unsafely interprets the variable's value:

$ var="=;echo pwned;_"
$ eval "hello_$var=value"
pwned

Not that export is perfect either, but at least you can't run arbitrary commands as far as I can tell:

$ export "hello_$var=value"
$ echo "$hello_"
;echo pwned;_=value

But it's still a tradeoff overall since it exports the variable (alternatively, you can use readonly); maybe there should just be a warning for the dangers of eval.

FriendlyNeighborhoodShane commented 4 years ago

@Crestwave I agree that eval is dangerous if used without caution, but I'd say handling arbitrary data from risky sources at all in shell (at least without sanitizing with something like sed "s|[^A-Za-z0-9_]||g") is the much bigger red flag in situations like this. If you're getting values from malicious sources, they can simply execute code with stuff like $(cmd) in normal assignments, no export or eval needed.

I concede that a warning should be added against eval, but I can't think of situation where assigning values to dynamically-named variables is useful if you're not able to access them in the same way dynamically.

All-in-all, I would likely never use it for something I wrote to be robust. But it's a really fun trick. I've been playing with it for the past few days and it's possible to create string-perfect lists and even composite data type or classes in shell.

Crestwave commented 4 years ago

If you're getting values from malicious sources, they can simply execute code with stuff like $(cmd) in normal assignments, no export or eval needed.

Huh? What do you mean by this? Can you give an example?

I concede that a warning should be added against eval, but I can't think of situation where assigning values to dynamically-named variables is useful if you're not able to access them in the same way dynamically.

Accessing dynamically-named variables can be done safely with eval as far as I know; I don't think naming them can without jumping through some hoops such as sanitizing it manually. Also, there is a use for that; see https://github.com/dylanaraps/pure-sh-bible#parsing-a-keyval-file, for example.

FriendlyNeighborhoodShane commented 4 years ago

@Crestwave

Huh? What do you mean by this? Can you give an example?

Never mind that, I wrote that wrong without thinking how parsing occurs in shells, my bad.

Accessing dynamically-named variables can be done safely with eval as far as I know; I don't think naming them can without jumping through some hoops such as sanitizing it manually.

Ah, I see the change you're suggesting.

I'll add some comments about eval's safety, and test a little and change eval to export for the assignment if it shows safer behaviour than eval, and then make a PR.