3 ms·
Many of these are due to the use of unstructured strings, which we do because we’re lazy. We’re so lazy about it that our modern languages don’t even support th
by ynniv 9y ago
Many of these are due to the use of unstructured strings, which we do because we’re lazy. We’re so lazy about it that our modern languages don’t even support the ability to distinguish user strings from application strings (perl’s taint mode). The workaround in development has been extensive testing, but this is insufficient in an adversarial environment. The best solution is to bring structure to your strings so that you can tasing about how they can be abused.
Parse your strings, kids.
- taeric 9y agoI challenge the "lazy" claim. We do it in large, because it is hard not to. At the border, you are either passing binary data around, or you are passing structured strings. Building structured strings to send through a border though, is often easiest done by building up an unstructured one and then sending it to the other side. Worse, it is not uncommon to find that the layer you are using to keep things structured becomes a major source of complexity in the application.
- minitech 9y ago> We’re so lazy about it that our modern languages don’t even support the ability to distinguish user strings from application strings (perl’s taint mode). “User strings vs. application strings” is too coarse. You just need to enforce types (a type for SQL – see query builders, a type for HTML – see MarkupSafe, etc.) and provide safe constructors for those types. Safe syntactic sugar for those is supported by JavaScript (template strings), Rust (macros), C++ (overloadable string literals), Haskell (overloadable string literals and Template Haskell), and probably plenty of other modern languages. For the others, explicit type wrappers are generally enough (like the aforementioned MarkupSafe in Python) – the only thing that’s lacking is enforcement by libraries.
- jlesk 9y agoThis is why I introduced LockStrings as a key feature of THT (a language that compiles to PHP). It takes the opposite approach to Perl's taint mode. You mark string literals as safe -- everything else is untrusted. Functions that do risky things (Database, System calls, etc.) only accept LockStrings and are responsible for escaping, so all you have to do is provide the placeholders. https://tht.help/tutorials/language-tour#lock-strings https://tht.help/tutorials/language-tour#lock-strings
- pornel 9y agoFor correctness it's not a binary yes/no problem of "trusted" vs "untrusted" (or "sanitised" vs "unsanitized"). Necessary escaping is dictated by context (such as HTML, JS, SQL, e-mail header), sometimes even nested multiple times (URL argument in JS in HTML attribute in a QP email body). Most tools and practices miss that point. This leads to creation of general-purpose (not type-safe) templating systems that can't automatically enforce correct escaping everywhere by default, so they leave it to programmers to do it manually where needed, which is error prone and ensures permanent OWASP entry as long as it exists. Also it's impossible to convince programmers to always implement "redundant" escaping for "harmless" values (such as IDs which are assumed to always be alphanumeric), which is a vulnerability waiting to be exploited (e.g. your policy is not to allow in '"' usernames, so you think you never need escape it, but then some code reads a username from a query string argument and game over).