3 ms·
> If I program in C, I need to defend against the compiler maintainers. > If I program in Go, the language maintainers defend me from my mistakes. > If you’re
by jitl 10y ago
> If I program in C, I need to defend against the compiler maintainers.
> If I program in Go, the language maintainers defend me from my mistakes.
> If you’re choosing software to deploy on your systems, which language would you rather that the vendors be writing in?
I think this is my favorite take-away. I spend a lot of time programming in Ruby, where more than a few parts of the standard library declare themselves to be security vulnerabilities, but there are no code-level protections to warn a programmer. I'm thinking specifically about FileUtils.rm_r, and all the various stdlib serialization modules that provide one or more ways to eval() when loading data. Is it YAML.load(x) or YAML.parse(x).to_ruby that's safe? I use YAML.safe_load, but how can I trust third-party libraries when the stdlib makes this SO EASY to get wrong?
+1 for the Golang maintainers and Go's approach here. Another reason to use Go...
- mnarayan01 10y ago> YAML.load(x) or YAML.parse(x).to_ruby If you're working with attacker controlled input, at best you can avoid evals while deserializing. As soon as you use the result, a sufficiently clever and informed attacker can almost certainly own you. YAML is just too powerful for anything else. If you're only using YAML as JSON with different syntax, that's a different story...but then you should just pass the library the deserialized data.
- deathanatos 10y ago> As soon as you use the result, a sufficiently clever and informed attacker can almost certainly own you. This is equivalent to saying that we should just not write any program, ever. > YAML is just too powerful for anything else. The problem the original author is getting at is that the library makes unsafe operations extremely easy to do. YAML the language is not inherently unsafe — it just serializes a data structure. But several YAML libraries (I believe both Ruby and Python are in this bucket) make it extremely easy to create objects of any arbitrary type, regardless of what the programmer expects, making arbitrary code execution either easy or trivial. Were the parse/load function something like, parse(input: serialized yaml, whitelisted_types) that only allowed reconstruction of core YAML types + whitelisted types that the user needs for his specific use case, the API would be fairly safe. (You could still shoot yourself in the whitelisted types part, of course, but again, yes, any user-controlled input handled poorly "could" be a bug.) This is a property of the construction of the API itself: the API encourages misuse.
- mnarayan01 10y agoI'm not trying to argue whether or not the API is well designed (the designers can do that if they so wish). My point is a pragmatic one: Saying the API lets you shoot yourself in the foot makes people believe that if they just use the right incantation everything will be fine and easy. YAML is just not that kind of format. If I was designing the API today, I would name YAML::load something like YAML::unsafe_load because loading YAML is dangerous. Guiding naive users to a high-restricted subset of YAML is good. Making them think that they just need to avoid "easy foot-guns" is not.
- deathanatos 10y ago> I'm not trying to argue whether or not the API is well designed (the designers can do that if they so wish). My point is a pragmatic one: Saying the API lets you shoot yourself in the foot makes people believe that if they just use the right incantation everything will be fine and easy. But that's my point: if you use the right incantation, everything should be fine-and-easy, even in languages like Ruby and Python. The larger point is that the library user shouldn't need to know the "right incantation"; the library should make the safe thing the default, and you should need to very explicitly shoot yourself in the foot. > YAML is just not that kind of format. > If I was designing the API today, I would name YAML::load something like YAML::unsafe_load because loading YAML is dangerous. Guiding naive users to a high-restricted subset of YAML is good. Making them think that they just need to avoid "easy foot-guns" is not. Reading your comment, I get the impression that you think YAML, as a format is unsafe; this isn't the case in any manner that I can see, and I explained a bit of that argument in my previous comment. The security issues have been around implementations of YAML libraries that allow the deserialization of custom tags that correspond to arbitrary language-specific objects (the !ruby tags). This isn't required by the YAML specification, and a library shouldn't do it by default because arbitrary object construction is dangerous. But YAML, as a format, doesn't require this; again, the core types + a whitelisted set of types covers 99% of use cases, and is safe. (And I think tagging is a great feature that basically appears in no other serialization format that I'm aware of. CBOR comes close, but you have to register your types w/ IANA.)
- thomasvendetta 10y agoAgreed, this brings to mind one of my favorites has never felt quite right: > require 'logger'; Logger.new("| cat ~/.ssh/id_rsa.pub")