Reputation: 21753
So we have a custom logger (really wanted to use Log4Net, just wouldn't work for this case). From a config file, you can configure the name of the table that will be inserted into.
I am parameterizing the insert statement, but the configurable table name will be used in an insert statement, and it's a potential vector for attack. Here's an example of the statement that will be built:
"insert into " + theTableName + " (static column list) values(parameterized list of values)"
So my inserted values are parameterized, and pretty safe, it's theTableName that could contain nasties.
My question is, what can I do to sanitize the table name? I think the nature of the code an attacker would inject would have to be a little different from the garden-variety. -- instead of a tick, you would potentially close off the statment with "table name() values(); do something bad --
(or something like that, I suppose). To that end, I was thinking about checking for the ";", and the "--".
Can anyone suggest a better way to sanitize this? (this will be used with Oracle and SQL server)
Upvotes: 0
Views: 222
Reputation: 17429
The obvious solution to me would be to validate the table name that you're going to use in the dynamic SQL using static SQL first:
select * from sys.tables where name = @thetablename
Since this query binds the variable rather than concatenating it, it should be immune to SQL injection. If the query returns a record then continue, otherwise handle it as an error.
Upvotes: 1
Reputation: 103587
why not use a theTableID
numeric ID value to a row where you store a table name theTableName
. You can store this numeric ID value in the config file on the user's PC and pass it into the application. Then you can look it up, via a parametrized query, and then concatenate the actual string table name into the query. That will be safe.
Upvotes: 1
Reputation: 333
I guess the main question is why theTableName variable is even being exposed to the person using the page that the logging is for.
Barring that, a whitelist check either against a set array of values or against a set that you create on the fly by querying the system catalog for table names and dumping them into an array and thing just doing a .Contains(theTableName) on the array or whatever the equivalent for your language of choice is probably the safest way to go.
Upvotes: 0
Reputation: 50970
I think you have a potentially bigger problem, which is that the user could specify a syntactically safe and valid table name that simply doesn't exist in the database.
Therefore, I'd do this:
Build the INSERT string (including the table name) only once, when you load the config file.
Verify the table name at that time by checking the system metadata to ensure that it's a real, valid table.
At that time you can warn the user that logging is off because the table "theTableName" does not exist in the database.
Upvotes: 1
Reputation: 38682
That still doesn't keep you safe from UNION-attacks (and several more). Best do some whitelist-check for latin letters or similiar if you know what's allowed.
Other characters to check for would be
()`"'
and whitespace.
Upvotes: 2