
Unauthenticated flag flipping yields remote code execution - ingve
https://rachelbythebay.com/w/2018/04/10/var/
======
jacquesm
I'm categorically against shelling out for _anything_ from a web based
service. If you need this sort of functionality implement a queue, send a
signal using some IPC process and wait until the job is done.

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.

~~~
pdkl95
> Ensure that the input you receive is not malicious

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.

[1]
[https://archive.org/details/The_Science_of_Insecurity_](https://archive.org/details/The_Science_of_Insecurity_)

~~~
jerf
There is another mathematically-correct layer of security you can get, though,
which is the IO interface to the real world that you provide the input.
Barring (huge!) bugs in the (very simple!) interpreter, it doesn't matter how
much basic brainfuck [1] from a user you execute, they aren't going to get a
shell. Worst they can do is burn CPU until you shut them down. (Brainfuck
interpreters are already generally pretty tightly RAM limited.)

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.

[1]:
[https://esolangs.org/wiki/Brainfuck](https://esolangs.org/wiki/Brainfuck)

------
glorbol
I disagree, shelling out to another program is a perfectly reasonable design
decision, one that has paid off in development speed. The people that run from
their OS like it's something to be scared of are really missing out on the
benefits of the their OS. I have built whole pipelines of essentially shell
commands and I have never had a command injection vulnerability because I
follow one simple rule:

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.

------
zerotolerance
I would have loved some concrete examples.

------
aperrien
Dang. Would containerization solve this, or at least help mitigate the damage?

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...

~~~
rachelbythebay
You could probably limit some of the insanity by walling off things that you
absolutely need to run and can't work around. Even then you still have to
worry about someone having too much fun inside the jail, container, or
whatever your system offers.

As for aspirin and friends, well, being effectively retired has done wonders
of late. But thanks!

------
gue5t
In short, ambient authority strikes again. Environment variables were a
terrible design mistake in UNIX.

~~~
rainieri
Very vague post. Next time please write specific examples. Everyone should
sanitize inputs.

~~~
Analemma_
> Everyone should sanitize inputs.

"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.

~~~
Karunamon
Ehh... how many instances of unsanitized input leading to RCE were due to the
subtleties of the interpreter, and how many are the result of people blithely
passing user input into the interpreter, not using the sanitation functions
available in most mainstream languages (in many cases, in the standard
library)?

If getting people to do this is impossible, so is getting people to stop
storing passwords in plaintext.

~~~
tomsmeding
> 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.

