It may, yes, though it is difficult to tell without knowing what the code is doing around that point. Anywhere where you take user input and place it into ad-doc SQL an easy injection route is presented to a malicious user simply by adding ' characters into the relevant input.
For instance if your code does something like:
results = dbObject.RunSQL("SELECT * FROM some_object WHERE person_name='" & request("name") & "'")
a malicious user can make a malformed HTTP request with the name
value containing '; DELETE * FROM users_table; SELECT '
the code you present to the database becomes:
SELECT * FROM some_object WHERE person_name=''; DELETE * FROM users_table; SELECT ''
Perfectly we formed SQL so it will run, and if you have a table called users_table
you have just lost its contents. There are much more clever attacks than this simple one possible by the same route. This isn't limited to SELECT
statements - any ad-hoc SQL is potentially vulnerable to this.
Without seeing some of the relevant code, what seems to be happening is some ad-hoc SQL is being put together with a string that contains apostrophe characters resulting in incorrect syntax. So you likely have a bug that creates an injection attack route, though in this instance the bug is simply causing an error doe to some specific input value. Find it and fix it while the force is with you! Instigate a full code review too, there may be many more examples of the problem.
To fix this sort of error you need to look at two things:
- Proper input validation. Refuse any request where a value seems to be in the wrong format. Expecting a UUID in a given variable? Then error and do nothing if you see anything that isn't a valid representation of that. Expecting a positive integer? Make sure the value contains nothing but numeric characters and throw out the request if not. Do this as early as possible, definitely before trying to touch your database with anything using values received from the client (in fact you should validate data from the database too before passing it back - bad data may have got into the database earlier either maliciously or due to a bug).
- Use parametrised queries where ever possible - avoid ad-hoc SQL except where absolutely necessary. Your data layer (ADO, OLEDB, ...) should handle this cleanly for you meaning you do not need to worry about it misinterpreting characters that have special meaning, for instance apostrophes sometimes found in names like
O'hare
. For bulk inserts/updates where single procedure calls per row are too inefficient consider using an updatable recordset rather than ad-hoc INSERT
statements if such a concept is supported.
- If you absolutely must put together ad-hoc SQL strings, be very very careful to escape special characters.
One thing I would recommend, though it can be costly, is having an instance of your application (not one containing real client data of course) properly penetration tested by a professional pen-testing company. The cost and hassle of this is nothing compared to losing all your data and/or customers if a hole they could have found is instead found and abused by a black-hat.
Best Answer
There is still a potential for injection here. Let's assume that:
That person could call this procedure to get results from
foo
, but in the meantime create a table called[foo;drop table bar]
, then passfoo;drop table bar
in as the parameter value. It would pass your check, then you would blindly execute it. They get the results fromfoo
but they also drop tablebar
.Now, that is a pretty contrived scenario, and you probably aren't worried about internal people dropping tables, but they could also use this to exploit data they don't have access to, for example they could create a table called
[foo;SELECT name,salary FROM dbo.Employees;]
and end up with two result sets, one with data you probably shouldn't be letting them see.There is also a potential for getting data from the wrong table, in the event that there are tables with the same names in different schemas. Always, always, always use the schema prefix when creating or referencing objects:
Finally, don't use
INFORMATION_SCHEMA
. The catalog views and metadata functions are much more complete, current and reliable:I would probably do it this way (and I'm going to assume for simplicity that all of your tables are in dbo):
This way, even if they pass
foo;drop table bar
orfoo;select name,salary from dbo.employees
as the table name, that whole string gets surrounded in square brackets, thus the worst thing that can happen is they'll get the results from the table they created, rather than any other table or worse.And I would ensure that the procedure runs as that user, rather than escalate using
EXECUTE AS
(a common bypass for proper permissions configuration). Also see: