|
|
|
|
|
by x1
5105 days 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 |
|
You're building a new query string each time you create a Query object, and concatenating the string onto that. With that approach, each time you build a Query object you have a fresh opportunity to mess up. So you're right that there's no difference between your to cases.
Let's drop my off-the-cuff example and look at how a real library, postgresql-simple, handles the issue:
Usage example Do you see the difference? Instead of sticking the username into the SQL query by hand, we use a query function that takes three parameters: a database handle, a Query with a '?' character, and a thing you want to use in the query. The function takes care of properly escaping the username during interpolation. (The "Only" is just a wrapper to make sure we're handing in a datatype we can query with.)Notice that because Query is a distinct type from String, just doing
doesn't typecheck. Bad Programmer would have a hard time screwing this up.The full documentation for postgresql-simple is here: http://hackage.haskell.org/packages/archive/postgresql-simpl...