3 ms·
How many security holes are caused by not sanitizing inputs, as opposed to memory safety? It feels like not sanitizing inputs is what enables memory safety expl
by 0xbadcafebee 2y ago
How many security holes are caused by not sanitizing inputs, as opposed to memory safety? It feels like not sanitizing inputs is what enables memory safety exploits, in addition to many other classes of security hole, yet nobody seems to talk about it.
- Buffer overflow: somebody didn't sanitize the input (length of buffer).
- Stack smashing: somebody didn't sanitize the input (length of input).
- Format string vulnerability: somebody didn't sanitize the format string data.
- Integer converstion vulnerability: somebody didn't sanitize the integer input.
- SQL injection: somebody didn't sanitize the input before querying a database.
- Cross-site scripting: somebody didn't sanitize input and it got submitted and executed on behalf of the user.
- Remote file inclusion / Directory traversal: somebody didn't sanitize an input variable leading to a file path.
...and on, and on, and on. If people were as obsessed with input sanitization as they are with memory, I'll bet you a much larger percentage of attacks would be stopped. Too bad input sanitization isn't sexy.
- UncleMeat 2y agoSQL Injection and XSS are actually great examples of vuln classes where the winning strategy is safe APIs rather than diligent sanitization. "Just sanitize all your user inputs" is hard to do correctly because it is difficult to create automatic rules that detect every single possible violation. Prepared statements and safe HTML construction APIs plus some linters that scream at you when you use the unsafe APIs works like magic.
- bflesch 2y agoYou're correct. It's about distinction between code and data. You should simply discern between HTML elements (code) and HTML text nodes (data). Same with prepared statements: Clear distinction between SQL code vs SQL data. You just need to ensure that your data is never interpreted as code.
- 0xbadcafebee 2y ago> You just need to ensure that your data is never interpreted as code. That's sanitization. Many different languages implement this. The old-school method is "tainting" data so it can't be used as part of execution without an explicit function call to "untaint" it. Same is used for "secret" data in various programs where you don't want it leaked.
- wepple 2y agoTwo reasons - modern languages prevent you from having to think about it at all. You shouldn’t have to sanitize, it should work - there are a load of issues that have nothing to do with sanitization but everything to do with memory. Race conditions, type confusion, UAF to name a couple. If we focus on sanitization, we still need memory safety to fix those Also sanitization is non-trivial for complex inputs
- wepple 2y agoYour distinction between stack smashing and buffer overflow is puzzling
- 0xbadcafebee 2y agoA buffer overflow is just exceeding the size of a buffer, and stack smashing is a modification of either the stack itself or the stack pointer to result in different operations on the stack. These methods can coincide, and they can also exist independently of each other
- wepple 2y agoYep. Hence my comment. Smashing the stack is an afterward condition of some kind of memory error. If you’re going to do that, why not mention heap overflow and others? It just seems unusual.
- crazygringo 2y ago> - SQL injection: somebody didn't sanitize the input before querying a database. > - Cross-site scripting: somebody didn't sanitize input and it got submitted and executed on behalf of the user. To be technical about it, this is generally a failure of escaping rather than sanitizing. You're supposed to be able to put anything into a database field and not have it affect the query. You ought to be able to paste JavaScript into a field and have it be displayed as JavaScript, not executed. The inputs remain as they are -- no sanitization -- they just have to be escaped properly. That being said, I'm 100% on board about the importance of sanitation/validation. To the extent I think it ought to be part of the design of languages just like types. I.e. if a function parameter is only allowed to be three string values, or a string between 0 and 10 bytes, or a string limited to lowercase ASCII, these should be expressable.
- GuB-42 2y agoSanitizing inputs in important in addition to memory safety. Sanitizing inputs won't protect you against all bugs. For example, you may store a string in a 256-byte buffer, so you check that the string is no longer than 256 characters, but you forget the zero-terminator, and you have a buffer overflow. Or maybe you properly limited the string to 255 characters, but along the way, you added support for multibyte characters, and you get another buffer overflow. Bound checking would have caught that. Injection can happen at any point. You may sanitize user input to avoid SQL injection, but at some later point it may get out of the database and in a format string, but it was sanitized for SQL, not for format strings, leading to a potential injection.
- lmm 2y ago"Sanitising" doesn't work. It's an exploit mitigation strategy, not a sound way of actually preventing bugs. And it doesn't prevent many of the vulnerabilities you list, because many of the things that cause issues don't come from "input" at all (e.g. a lot of buffer overflows can be triggered with "legitimate" input that isn't and couldn't be caught by input sanitisation).
- 0xbadcafebee 2y ago> It's an exploit mitigation strategy, not a sound way of actually preventing bugs. Actually it is a simple and effective way to prevent general bugs. If you have an input field called birthday, you can inject it directly into your database. Doing that could cause an SQL injection exploit, so people use prepared statements. But even if you use prepared statements, you'll still end up with a database column with all kinds of birthday formatting (M-D-Y, Y-M-D, slashes, spaces, colons, etc etc). These different, non-standard formats will eventually cause a bug. Input sanitization forces you to standardize on one birthday format, and inject it into your database in one format (let's say "YYYY-MM-DD", no other characters allowed). Then all the code expects - and gets - one format. This reduces bugs from unexpected formats. It has the added side-effect of also eliminating the SQL injection bug, regardless of prepared statement.
- lmm 2y ago> Input sanitization forces you to standardize on one birthday format, and inject it into your database in one format (let's say "YYYY-MM-DD", no other characters allowed). Then all the code expects - and gets - one format. That's not sanitisation as the word is normally used. That's parsing and canonicalisation. That's a good path to actual security - it leads you to the "make invalid states unrepresentable" style and using decent type systems.