Rpostgresql: Properly escaping strings for input - sql

I am bridging R and psql, wish to remove vulnerability to sql injection. Looking at documentation, I had hoped that:
postgresqlExecStatement(con, statement, params, ...)
Would allow use of something like:
postgresqlExecStatement(con, "DELETE FROM foos WHERE id = ? AND baz = ?", c(1, "bar"))
But unfortunately this does not seem to work. Maybe I'm using the wrong
symbol for parameter (something other than ?).
Best compromise I've found is escaping strings via:
postgresqlEscapeStrings(con, string)
(note: connection is necessary so function can know how to properly escape).
Means I have to escape every string I use in a paste when putting together
my queries. Not so elegant. But seems best option. Anyone have other
ideas?

Use
postgresqlExecStatement(con, "DELETE FROM foos WHERE id = $1 AND baz = $2", list(1, "bar"))
I always pass my parameters to be bound as a list since c will force it into one mode. You also have to clear the results belonging to con if this statement succeeds before you can use it again.
Also, please note hadley's comments to use the new package RPostgres.

Related

VisualBasic OleDb accessing Excel spreadsheet, can't set column in query using parameter?

I'm working in Visual Basic and using OleDb to access an Excel spreadsheet. I'm importing the data from the sheet into my DataGridView, and that works fine, but now I'm working on filtering. For the most part it works great, but I'm trying to use parameters ("#p1" and so on), and I'm getting a very strange issue.
I can have the following (excluding a bunch of irrelevant stuff before, in between, and after)
query = query & "Project" & " LIKE #Gah1"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "%House%")
and it gives me the results I'm looking for. But I can't seem to get a parameter for the name of the column itself, for example
query = query & "#Gah1" & " LIKE #Gah2"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "Project")
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah2", "%House%")
does not work (and I've tried enclosing Project in different brackets and stuff in different ways, can't get it to work). I've found plenty of examples on using parameters, but none that use them to give the column name.
I'm guessing the parameter changes how the string is represented, seeing as you don't need to have the ' ' around string literals.
Is it not possible to give column names in parameter? If you can, what do I need to do?
Well it won't let me post comment, so here
a) Oops, no, I guess not
b) The string query that I end up sending in my test query here is
"select * from [Bid Summary$] where #Gah1 LIKE #Gah2"
I can post the procedure if absolutely need be, but it isn't the problem because the whole thing works perfectly fine if I replace #Gah1 with Project or [Project], so I just showed the lines that I change.
I'm very new to parameterized queries, can you explain how to avoid query strings using it? If there's a better way to do what I'm doing I'm happy to use it =)
And thanks for response and edit
I use combination of string methods and parameters, like this:
//replace field name in a query template
query = String.Format("select * from [Bid Summary$] where {0} LIKE ?", "#Gah1");
//set value (name is in OleDb parameter ignored, so it could be null)
MyCommand.SelectCommand.Parameters.AddWithValue(null, "%House%");
Note: There is possibility of a sql injection, so be sure about origin of field name (not from user input).

Is there a way to use the LIKE operator from an entity framework query?

OK, I want to use the LIKE keyword from an Entity Framework query for a rather unorthodox reason - I want to match strings more precisely than when using the equals operator.
Because the equals operator automatically pads the string to be matched with spaces such that col = 'foo ' will actually return a row where col equals 'foo' OR 'foo ', I want to force trailing whitespaces to be taken into account, and the LIKE operator actually does that.
I know that you can coerce Entity Framework into using the LIKE operator using .StartsWith, .EndsWith, and .Contains in a query. However, as might be expected, this causes EF to prefix, suffix, and surround the queried text with wildcard % characters. Is there a way I can actually get Entity Framework to directly use the LIKE operator in SQL to match a string in a query of mine, without adding wildcard characters? Ideally it would look like this:
string usernameToMatch = "admin ";
if (context.Users.Where(usr => usr.Username.Like(usernameToMatch)).Any()) {
// An account with username 'admin ' ACTUALLY exists
}
else {
// An account with username 'admin' may exist, but 'admin ' doesn't
}
I can't find a way to do this directly; right now, the best I can think of is this hack:
context.Users.Where(usr =>
usr.Username.StartsWith(usernameToMatch) &&
usr.Username.EndsWith(usernameToMatch) &&
usr.Username == usernameToMatch
)
Is there a better way? By the way I don't want to use PATINDEX because it looks like a SQL Server-specific thing, not portable between databases.
There isn't a way to get EF to use LIKE in its query, However you could write a stored procedure that finds users using LIKE with an input parameter and use EF to hit your stored procedure.
Your particular situation however seems to be more of a data integrity issue though. You shouldn't be allowing users to register usernames that start or end with a space (username.Trim()) for pretty much this reason. Once you do that then this particular issue goes away entirely.
Also, allowing 'rough' matches on authentication details is beyond insecure. Don't do it.
Well there doesn't seem to be a way to get EF to use the LIKE operator without padding it at the beginning or end with wildcard characters, as I mentioned in my question, so I ended up using this combination which, while a bit ugly, has the same effect as a LIKE without any wildcards:
context.Users.Where(usr =>
usr.Username.StartsWith(usernameToMatch) &&
usr.Username.EndsWith(usernameToMatch) &&
usr.Username == usernameToMatch
)
So, if the value is LIKE '[usernameToMatch]%' and it's LIKE '%[usernameToMatch]' and it = '[usernameToMatch]' then it matches exactly.

Protecting against SQL injection in python

I have some code in Python that sets a char(80) value in an sqlite DB.
The string is obtained directly from the user through a text input field and sent back to the server with a POST method in a JSON structure.
On the server side I currently pass the string to a method calling the SQL UPDATE operation.
It works, but I'm aware it is not safe at all.
I expect that the client side is unsafe anyway, so any protection is to be put on the server side. What can I do to secure the UPDATE operation agains SQL injection ?
A function that would "quote" the text so that it can't confuse the SQL parser is what I'm looking for. I expect such function exist but couldn't find it.
Edit:
Here is my current code setting the char field name label:
def setLabel( self, userId, refId, label ):
self._db.cursor().execute( """
UPDATE items SET label = ? WHERE userId IS ? AND refId IS ?""", ( label, userId, refId) )
self._db.commit()
From the documentation:
con.execute("insert into person(firstname) values (?)", ("Joe",))
This escapes "Joe", so what you want is
con.execute("insert into person(firstname) values (?)", (firstname_from_client,))
The DB-API's .execute() supports parameter substitution which will take care of escaping for you, its mentioned near the top of the docs; http://docs.python.org/library/sqlite3.html above Never do this -- insecure.
Noooo... USE BIND VARIABLES! That's what they're there for. See this
Another name for the technique is parameterized sql (I think "bind variables" may be the name used with Oracle specifically).

SQLiteQueryBuilder.buildQuery not using selectArgs?

Alright, I'm trying to query a sqlite database. I was trying to be good and use the query method of SQLiteDatabase and pass in the values in the selectArgs parameter to ensure everything got properly escaped, but it wouldn't work. I never got any rows returned (no errors, either).
I started getting curious about the SQL that this generated so I did some more poking around and found SQLiteQueryBuilder (and apparently Stack Overflow doesn't handle links with parentheses in them well, so I can't link to the anchor for the buildQuery method), which I assume uses the same logic to generate the SQL statement. I did this:
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(BarcodeDb.Barcodes.TABLE_NAME);
String sql = builder.buildQuery(new String[] { BarcodeDb.Barcodes.ID, BarcodeDb.Barcodes.TIMESTAMP, BarcodeDb.Barcodes.TYPE, BarcodeDb.Barcodes.VALUE },
"? = '?' AND ? = '?'",
new String[] { BarcodeDb.Barcodes.VALUE, barcode.getValue(), BarcodeDb.Barcodes.TYPE, barcode.getType()},
null, null, null, null);
Log.d(tag, "Query is: " + sql);
The SQL that gets logged at this point is:
SELECT _id, timestamp, type, value FROM barcodes WHERE (? = '?' AND ? = '?')
However, here's what the documentation for SQLiteQueryBuilder.buildQuery says about the selectAgs parameter:
You may include ?s in selection, which
will be replaced by the values from
selectionArgs, in order that they
appear in the selection.
...but it isn't working. Any ideas?
The doc for SQLiteQueryBuilder.buildQuery also says, "The values will be bound as Strings." This tells me that it is doing the straight-forward thing, which is writing the SQL leaving the ? parameter markers in place, which is what you are seeing, and binding the selectArgs as input parameters.
The ? are replaced by sqlite when it runs the query, not in the SQL string. The first string in the array will go where you see the first ?, and so on, when the query actually executes. I would expect the logged SQL to still have the ? markers.
Probably, your query fails because you are quoting the ?. For example, don't use WHERE ID = '?', just use WHERE ID = ?, and make sure the selectArgs is a string that satisfies the query.
Two things:
The ? substitution will not be done at this point, but only when the query is executed by the SQLiteDatabase.
From what I've seen, ? substitution only works for the right side of comparison clauses. For example, some people have tried to use ? for the table name, which blows up. I haven't seen anyone try using ? for the left side of the comparison clause, so it might work -- I'm just warning you that it might not.

How to quote values for LuaSQL?

LuaSQL, which seems to be the canonical library for most SQL database systems in Lua, doesn't seem to have any facilities for quoting/escaping values in queries. I'm writing an application that uses SQLite as a backend, and I'd love to use an interface like the one specified by Python's DB-API:
c.execute('select * from stocks where symbol=?', t)
but I'd even settle for something even dumber, like:
conn:execute("select * from stocks where symbol=" + luasql.sqlite.quote(t))
Are there any other Lua libraries that support quoting for SQLite? (LuaSQLite3 doesn't seem to.) Or am I missing something about LuaSQL? I'm worried about rolling my own solution (with regexes or something) and getting it wrong. Should I just write a wrapper for sqlite3_snprintf?
I haven't looked at LuaSQL in a while but last time I checked it didn't support it. I use Lua-Sqlite3.
require("sqlite3")
db = sqlite3.open_memory()
db:exec[[ CREATE TABLE tbl( first_name TEXT, last_name TEXT ); ]]
stmt = db:prepare[[ INSERT INTO tbl(first_name, last_name) VALUES(:first_name, :last_name) ]]
stmt:bind({first_name="hawkeye", last_name="pierce"}):exec()
stmt:bind({first_name="henry", last_name="blake"}):exec()
for r in db:rows("SELECT * FROM tbl") do
print(r.first_name,r.last_name)
end
LuaSQLite3 as well an any other low level binding to SQLite offers prepared statements with variable parameters; these use methods to bind values to the statement parameters. Since SQLite does not interpret the binding values, there is simply no possibility of an SQL injection. This is by far the safest (and best performing) approach.
uroc shows an example of using the bind methods with prepared statements.
By the way in Lua SQL there is an undocumented escape function for the sqlite3 driver in conn:escape where conn is a connection variable.
For example with the code
print ("con:escape works. test'test = "..con:escape("test'test"))
the result is:
con:escape works. test'test = test''test
I actually tried that to see what it'd do. Apparently there is also such a function for their postgres driver too. I found this by looking at the tests they had.
Hope this helps.