4 ms·
Time and time again, don't `trust' user data -- sanitize it before passing to subsystem or DSL. No matter how unprobable it seems for user to be able to insert
by dexen 14y ago
Time and time again, don't `trust' user data -- sanitize it before passing to subsystem or DSL. No matter how unprobable it seems for user to be able to insert unexpected characters.
- lmm 14y agoDon't "sanitize" either, it's next-to-impossible to get right. Treat anything that came from user input as tainted (your language should be able to help you with this), and never pass a tainted string to a database except as a parameter.
- evincarofautumn 14y agoWhitelisting works better than blacklisting, I think. You can accidentally make a whitelist too permissive, but at least you can correct it after the fact. A blacklist might never be restrictive enough, and you will end up fighting a losing battle. So a function “sanitize :: Tainted a → Filter a b → b” is acceptable as long as individual filters are secure.
- patio11 14y agoI'm not sure I'm reading your notation right. Do I understand correctly that you think two sanitization functions applied in sequence are safe if both functions applied by themselves are safe? I think that that is true as a mathematical statement but often gets explosively disproven in production systems, because e.g. you can exploit different assumptions made by the filters in ways which were not anticipated (to say nothing of formally proven to be impossible), such that once-safe input becomes viable attack code. For example, if you have both a) unicode canonicalization and b) escape_single_quotes() running around your application, I really do not like your chances of beating a fuzzer (plus, optionally, a pen-tester who understands encoding issues).
- evincarofautumn 14y agoSorry, perhaps you may find “template<class A, class B> B sanitize(Tainted<A> tainted, Filter<A, B> filter)” more readable. I was saying that “sanitize” is fine in principle—it’s unexpected interaction between filters that’s dangerous, as you say. The problem is that input filters seem more composable than they actually are. I think the best you can do in practice is attack your code with a large number of random inputs and assert that the expected properties hold.