7 ms·
> But if you write a secure version, you only have to write it once. > You only have to maintain it in one place. > You only need to test it in one place. Ag
by x1 14y ago
> But if you write a secure version, you only have to write it once.
> You only have to maintain it in one place.
> You only need to test it in one place.
Again, so this cannot be done in a dynamic language? If it can be done, why bring them up?
> And if you forget to use your secure Query type, anywhere else in your code, the compiler will yell at you. It's a significant advantage.
The only thing the compiler will yell at you is if you passed a type that is not of a Query type. The compiler will not yell at you for getting the current session directly or creating your own jdbc driver for that matter.
- zopa 14y ago> "The only thing the compiler will yell at you is if you passed a type that is not of a Query type. The compiler will not yell at you for getting the current session directly or creating your own jdbc driver for that matter." In Haskell, I'd have a module, Database, that held all my db code. That module would export functions something like query :: Query -> DBResult update :: Query -> DBAction -> DBResult (read those as "query is a function that takes a Query and returns a DBResult.") In the rest of my program, those functions would be the only way to talk to the database. There's your guarantee. Could I, rather than using my nice database module, instead drop into IO and write code to do something vicious? Surely. But now we've moved beyond bugs and into active malice. > "Again, so this cannot be done in a dynamic language? If it can be done, why bring them up?" It's harder. With duck typing, if it looks like a Query it is a Query, no? Even if it drops your table. I'm no expert on dynamic languages, and I'd believe that there are sophisticated object hierarchies that can do these things (at runtime...), but the original article is empirical evidence that real projects get this wrong. Really, though, try a language with a modern type system and see for yourself. I know we Haskell users sound like zealots, but the difference between the Java and Haskell type systems truly is night and day.
- x1 14y ago> In the rest of my program, those functions would be the only way to talk to the database. There's your guarantee. Honest question. Take these pseudo sql calls: //Bad Person username = "lastname'; drop table user--" //Good Programmer query = "select * from users where name like %[username]%"; input = {"username":"frank"}; result = execute(query,input); //Bad Programmer query = "select * from users where name like '%"+username+"%'"; result = execute(query, {}); vs //Bad Person String username = "lastname'; drop table user--" //Good Programmer Query q = new Query("select * from users where name like %[username]%"); Input input = new Input(username); q.addInput(input); Result r = q.execute(); //Bad Programmer Query q = new Query("select * from users where name like '%"+username+"%'"); Result r = q.execute(); Could you solve this better using a static system? Right now I see no difference between the good and bad
- papsosouid 14y agoIn your static example, "Bad Programmer" would be fine, because the Query constructor does escaping. You could do this in a dynamically typed language too, but notice that you don't, you just use strings. The difference between static and dynamic is that with static typing, you can't compile your incorrect program. With dynamic typing, you find out at run time that you forgot to escape the string (turning it into a Query), when that code actually runs.
- deleted 14y ago[deleted]
- deleted 14y ago[deleted]
- jaylevitt 14y agoI'm admittedly ignorant of any type system newer than C++. In a modern static language, how would you design Query such that any SQL injection is caught at compile-time? On the dynamic side, Rails (in Ruby) doesn't currently catch SQL injections, but it does catch HTML-escaping injections. It (roughly) tags all strings as tainted by default, and when you send them to the browser, it escapes them. If you want to send literal ampersands, angle brackets, etc., you have to mark them as explicitly safe. Since most of your literal HTML is generated by templates (which themselves distinguish variables from static HTML), you end up with run-time safety unless you actively try to break out of it.
- zopa 14y agoSee http://news.ycombinator.com/item?id=4139798 http://news.ycombinator.com/item?id=4139798
- Peaker 14y agoIf he builds the final query string before giving it to Query, his valid query parts that rely on not being escaped would also be escaped. To make a safe query type you'd have to provide non-string primitives to build one, if I understand correctly. You can't allow just a full query string (with all of the injections already in place) to be converted to a Query type (as in his Bad Programmer example).