3 ms·
Sanitisation is relying on parsing (tricky as we see here) and on removing "special" characters (meaning that some otherwise valid values can't be represented)
by pilif 5y ago
Sanitisation is relying on parsing (tricky as we see here) and on removing "special" characters (meaning that some otherwise valid values can't be represented)
What you should be using is quoting and escaping for the specific context.
Here in PHP and in the shell command argument position, you'd use `escapeshellarg()`. This will produce a correctly quoted and escaped string that can be safely used at argument position in a shell command.
It also doesn't rely on knowledge of the specific domain of the argument and it doesn't parse the argument at all. It's stateless and works everywhere.
Of course, if the input isn't a valid hostname, to come back to this article, `ping` will still fail, but there will be no possibility for arbitrary code execution (of course, neither their would be if `filter` worked right, but that's a) accidental (because ; and ' are not valid host name characters) and b) obviously not a given because filtering and sanitisation is much harder than dumb quoting.
Always quote. Only validate if you need to produce a readable error message. But never rely on validation or sanitisation.
- dgb23 5y agoValidate when you get it, escape when you use it.
- km6GEwiQqsyEKQH 5y agoEscaping shell arguments is still fighting self-erected bugstacles. Why run the sub process in a shell in the first place? Why make a string out of your argument list for the shell to parse it back to a list to finally call the process? Just exec the program directly with the argument list and do not escape anything. Just skip the dance of serializing your arguments to a string.
- __david__ 5y agoUnfortunately, PHP is the one scripting language that doesn't have direct exec() support! escapeshellarg() is the only tool they give you and it requires you to not shoot yourself in the foot. Even perl has multi arg system() that execs directly.
- pilif 5y agothere is pcntl_exec for that. Unfortunately it can be (and often is) disabled and thus not widely used.
- maple3142 5y agoEven escapeshellarg might not be enough, because the command you are executing might trying to parse it as options. Depends on which command you are using, it could be exploitable. For example, there is a CTF challenge where you need to get RCE by passing a argument to wget escaped by escapeshellarg. (https://github.com/CykuTW/My-CTF-Challenges/blob/master/TSJ-CTF-2022/wgetshell/solution/README.md https://github.com/CykuTW/My-CTF-Challenges/blob/master/TSJ-...)