SQL injection: isn't replace("'", "''") good enough?
Solution 1
No, it is not enough. It will do in a pinch, but it is a very weak alternative, and using parameterized queries or parameterized stored procedures is better, if your platform and/or RDBMS support either feature.
From
OWASP's SQL Injection Prevention Cheat Sheet
...this methodology is frail compared to using parameterized queries. This technique should only be used, with caution, to retrofit legacy code in a cost effective way.
There are more below
SQL injection — but why isn't escape quotes safe anymore?
Sql Injection Myths and Fallacies
SQL Injection after removing all single-quotes and dash-characters
Solution 2
Yes, .Replace("'", "''")
stops SQL injection to the same degree that parameterization does.
There is still double or reflective injection. For example, you can store
'; delete from orders'
in a comment field. If part of the database uses the comment field in dynamic SQL, it might run the delete instead.
Solution 3
If the user only needs read only access to the data then have the UI execute via a SQL user that only has read only access. Read only does not protect you from injection attacks - they can use it to view data you did not intend them to view but they cannot use injection to delete data.
Solution 4
I think you're getting an answer on the way as to why it isn't enough, but you also run into the problem of somebody forgetting to do a replace on a string. If you 'always' use parameters, this is less of an issue.
![Mr Lister](https://i.stack.imgur.com/Gw5Un.png?s=256&g=1)
Mr Lister
I know about C, CS, CSS, SCSS and so on. C++, not a problem whatsoever. The trick is to avoid new. Some JS implementations still scare me though. "return less than hr divided by greater than"? Anyway, #SOreadyToHelp! Warning: I downvote answers that suggest z-index:1000000000 or !important as solutions to CSS problems. Mozilla user since 1997. Continuously. No matter the name. "Error: your new password is easy to remember. Please choose a password that is impossible to remember instead." My hobby: flagging comments that say "This question is off topic because it happens to contain the word SEO" 4 March 2020: celebrating 10 years of the official death of MSIE6. Hurray! Oh wait. "We value your privacy! So we won't let you in until you accept tracking cookies." 20 years of experience in JavaScript and today I found you don't need a temporary to swap two variables. Well.
Updated on August 24, 2022Comments
-
Mr Lister almost 2 years
While I can certainly see the advantages of using parameters for SQL queries, especially when dealing with datetimes and things like that, I'm still unsure about parameters as the only way to prevent SQL injection.
The fact is, I inherited an application and it has things like"SELECT Field FROM Table WHERE Filter='"+userinput.Replace("'", "''")+"'"
all over the place. Now while those doesn't look very pleasant to my eyes, and I wouldn't mind rewriting them, my question is, do I need to? Try as I might, I can't see a way to perform SQL injection with this.
-
Polynomial over 12 yearsI particularly like this post: codeinsecurity.wordpress.com/2011/12/09/…
-
Andomar over 12 years@Polynomial: that post doesn't apply to this query. Here, the user input cannot escape being inside a string.
-
Mike M. over 12 yearsI was going to argue against your original post which was incredibly against this method, but it seems doing some research has brought you a more reasonable viewpoint :). Sure, It's not the best method, but if it's in place, I don't see a total re-write of all data access being necessary unless you find yourself with the time.
-
David over 12 years@Mike M. - Oh, I'm still incredibly against it if you can reasonably use a better method. I just took the time to re-word my answer to a less "extreme" statement as I found the links I was looking for. I agree that re-writing an entire application to get rid of escaped characters is probably not justified, but fixing them while you're in that section of code would be worth it to me. I have an unfortunate tendency to make extreme statements when I'm in shoot-from-the-hip mode.
-
Mike M. over 12 years@DavidStratton Completely agree!
-
dburges over 12 yearsIf you are refactoring anyway, why not go to the best practice at the same time?
-
paparazzo over 12 yearsI agree. You only need to miss a string replace in one spot and it is game over.
-
Mr Lister over 12 yearsThanks all. All valuable, if somewhat contradictory, info. I know what I should do now, and if I get the time, I certainly will!
-
Mr Lister over 12 yearsGood one, but in this case not applicable I'm afraid. I can keep it in mind for any next projects though.
-
Orhun Alp Oral over 10 yearsPlease give some simple reasons/examples why it is not good enough instead of giving alternative advices..
-
SQL Police over 8 yearsI don't understand that answer. How could your input example be an exploit for the OP's question ? He is escaping the single quote, so I sese no chance.
-
Andomar over 8 years@SQLPolice: For example,
declare @sql nvarchar(max); select @sql = 'select ''' + Field + '''' from yourtable; exec (@sql);
-
SQL Police over 8 yearsbut the OP is escaping all single quotes. See the
replace
statement. The sql string becomes a normal string then, it will not be seen as executable code. -
Michael Z. about 8 yearsActually, if you know your database and your code will only talk to that database system and you only escape when you need to write to the database then it works perfectly fine and no other string manipulation is required to eliminate SQL Injection. It is good practice to use prepared statements so that your code can work across different database systems.
-
BlackICE over 5 yearsYour first statement:
Yes, .Replace("'", "''") stops SQL injection to the same degree that parameterization does.
is completely incorrect, even when it was written.