Unauthenticated flag flipping yields remote code execution
rachelbythebay.com
rachelbythebay.com
Exec'ing anything (even Postscript, which is after all a full fledged programming language) is a huge risk. Ensure that the input you receive is not malicious and if you can recompile any executables that will process hostile inputs to process only the subset of commands and functions that you think should be able to deal with untrusted input.
And of course you still have to properly sandbox those programs.
1. Those command line programs weren't necessarily designed with an adversarial user in mind! Sanitizing input to prevent shell escape sequences is not enough. You really need to sandbox well.
2. For some tasks, it might be easy for a malicious user to guess which command-line tool you are using. You might be getting way less depth out of obscurity than you think you are.
To do that input needs to be decidable. Input from possibly-malicious sources needs to be limited to a grammar no more complex than deterministic context-free[1]. Accepting Turing complete input introduces the possibility that recognizing anything about the input might be provably undecidable.
Sandboxing is of course easier said than done, but it's still mathematically valid. The problem is that our real hardware has too many metaphorical sharp edges from a mathematical point of view, not that it doesn't work.
I filter and sanitize input as soon as I receive it from the user. There are an infinitesimally small number of instances where you need to process anything but [a-zA-Z0-9]+ charset in a shell pipeline.
Once you have a pattern down for safely executing commands, there is no reason to be scared. It's really a myth that you can't become "secure", and this author's blog post is a perfect example. Tell me how you will conduct command injection when you have a whitelist of a-z0-9. I need an example, instead of this fear mongering that your OS is something to run and hide from.
Rachel's stories are always interesting, I always find myself learning new things from them, and I have been for over a decade now. They are a great reminder of my sysadmin past, now that I mostly do DBA work anymore. However, I do wonder if I should be sending her aspirin or tequila as tribute at times...
As for aspirin and friends, well, being effectively retired has done wonders of late. But thanks!
"Sanitize your inputs!" is the security equivalent of abstinence-only sex education. Yes, it technically will fix the problem if executed perfectly, but an endless history of failure should have convinced everyone by now that it is not the right solution for the real world. As other commenters have pointed out, shells were never designed with adversarial input in mind and so "sanitizing" them means hunting down and endless number of bugs and still not knowing if you've done it correctly.
The correct way is to design from the start so that user input cannot be executed. For SQL, everyone now knows that means parametrized statements; in this case, it means job queues and standalone processes with locked-down privileges.
If getting people to do this is impossible, so is getting people to stop storing passwords in plaintext.
This may very well be the case, though. You may get most people to know that storing passwords in plaintext is not a great idea (tm), but there will always be people ignoring that, be it due to downright ignorance or external factors.
I can envision some non-technical person in an organisation prescribing to IT that a new user password cannot look like one of the user's old passwords, where "look like" actually means something like an edit distance of <=2. Since the secure way of implementing this is looping over all possible passwords close to the one the user entered now, hashing them all and comparing them to a list of past hashes (which is quite resource-intensive, which costs mony), I bet there will be people that will give in and just store the last few passwords in plaintext. Maybe they'll encrypt them, but they'll be there.
Security in depth is hamstrung by an ever-increasing surface area.
I mean, people doing things wrong isn't evidence that they cannot be done right... right?
Imagine a website that will take an URL and extract the text from it - removing markup - or another service that will scan a URL for meta-tags, etc. All the kind of things that you can find easily.
Now imagine what happens if a user passes input such as "file:////etc/passwd". There are a whole bunch of services which will spit out the contents of the file, because they use some URL-fetching library and don't limit the protocols to http or https.
I wrote a blog-post about that, which was featured here a while back:
It doesn't stop me from supporting it as a deployment process, but there's a 22 year old inside of me that cries a little every time I talk about using environment variables for config.