Escaping Strings in SQL Server - sql-server

Am having issues with escaping parts of strings in SQL. On example is:
SELECT TOP 10000 *
FROM experience
WHERE name IS
'AT&T'
Which is saying incorrect syntax near Incorrect syntax near 'AT'. Seems its an issue with the & - is there any general rule to escaping?
Have also tried
SELECT TOP 10000 *
FROM experience
WHERE name Like
'AT&\T'
This works, although gives no results (there are results which should come up)

The only character that needs escaping in a string literal is the single quote. '. This is escaped by doubling them up instead of with a backslash.
SELECT 'O''Reilly'
In the vast majority of cases you should be using parameterised queries anyway and never need to even do that.
The correct operator to use is =
SELECT TOP 10000 *
FROM experience
WHERE name = 'AT&T'
Works Fine SQL Fiddle Demo
IS is only used in conjunction with [NOT] NULL
The only special significance backslash has in a string literal is if immediately before a line break when it acts as a line continuation character.
PRINT 'This is all \
one line'
Returns
This is all one line

Related

SQL Pattern matching not giving the correct output

I am trying to find a certain set of characters in a column from a datatable. I have tried the pattern that seems more logical to me (right below) but it doesn't seem to be doing the job. What I wish to achieve is a pattern where I have something like '["5"]', basically with: square brackets, quotation marks, any integer number, quotation marks, square brackets. The output I am getting is just empty, and I can't seem to undersand why. Besides this, I would like to update the records that do not follow this pattern to follow it. Does anyone have a solution for this?
To give you some context, here is the test table:
I want to achive only the last three records.
Here is what I have tried:
SELECT ToJsonTestValue
FROM Test
WHERE ToJsonTestValue LIKE '["%"]'
and
UPDATE dbo.Test
SET ToJsonTestValue = '["'+ToJsonTestValue+'"]'
WHERE ToJsonTestValue LIKE '#';
You have a couple of problem here. Firstly you have the square brackets, which needs escaping. Then you also use % which is a multi character wildcard, however, it appears that you want a single character. It also appears that that character can only be an integer, so you might want to be more specific. Either of these should give you the result you want:
--Using single character wildcard:
SELECT *
FROM (VALUES('["1"]'),('["["1"]"]'))V(S)
WHERE V.S LIKE '[[]"_"[\]]' ESCAPE '\';
--Specifically requiring int:
SELECT *
FROM (VALUES('["1"]'),('["["1"]"]'))V(S)
WHERE V.S LIKE '[[]"[0-9]"[\]]' ESCAPE '\';

How do I do quotes within quotes in TSQL

I have a case statement that will set a varchar variable #stored_proc_name to the name of a procedure that I want to call later on. One of the procedures I want to call takes a varchar as an argument (and also an int). How do I do this? Currently what I have is this
SELECT #stored_proc_name = CASE #p_process_name
WHEN 'misdate' THEN 'findb..sp_cycle_date_daily'
WHEN 'balpremmis' THEN 'findb..pc_bal_writ_prem'
WHEN 'ursctl' THEN 'MIS_feeds..pc_mis_update_feed_control "URSPO", 1'
ELSE NULL
END
EXECUTE #stored_proc_name
The last one is my procedure that takes arguments, where "URSPO" should be the first, and 1 is the int. It is running on SQL server 2k8 (I think I remember some difference with single vs. double quotes between this and older versions). Is what I have correct? I admit that I haven't tested it yet, but it is a part of a huge process that I really don't want to kick off right now.
Thank for any help!
To escape a single quote inside a string literal, use a double quote like below. See the Constants section in the BOL for more information:
select ' '' ' -- creates a string containing a space, a single quote, and another space
In your example, this would be the string:
'MIS_feeds..pc_mis_update_feed_control ''URSPO'', 1'
If you were going to use this string in a LIKE expression, you might want to refer to this question.
And if you were going to build a string to be a SQL identifier, you might want to escape it using the QUOTENAME function.
You can use the code below:
set quoted_identifier off;
Select "'Hi'"
quoted_identifiere will enable you to use ", instead of ';

Single-Double quotes error in Full Text Search

I am run into trouble.If type in Single-Double quotes in search statement will raise up a error,My sql statement like this:
SELECT UsersID,Sex,Age FROM dbo.UserBasicInfo WHERE
CONTAINS(PositionDesired,'"*"JAVA*"')
The error message:
Msg 7630, Level 15, State 3, Line 1
Syntax error near 'JAVA*' in the full-text search condition '"*"JAVA*"'.
Assume that the result must contains Single-Double quotes like: "JAVA"PHP" How to do?
Thanks !
You have an extra embedded double quote:
CONTAINS(PositionDesired,'"*"JAVA*"')
----------------------------^
This effectively terminates the string early, and SQL Server doesn't understand what that extra stuff is.
Should be (I think, not a full-text guru):
CONTAINS(PositionDesired,'"*JAVA*"')
However, I think that will eliminate the error, but not return the results you are after, since punctuation is ignored. You may have to use a combination of CONTAINS and LIKE, e.g.:
CONTAINS(PositionDesired,'JAVA')
AND PositionDesired LIKE '%"JAVA"%'
Or for the new requirement you've added:
CONTAINS(PositionDesired,'JAVA PHP')
AND PositionDesired LIKE '%"JAVA"PHP%"'
In the LIKE clause you don't have to worry about escaping or doubling-up the double quote, because it isn't a string delimiter there.
Hopefully the CONTAINS clause will filter results first, but even in a normal query there is no guarantee of short-circuiting or order of evaluation; I have no idea about a query with full-text and standard filters.

Real examples of SQL injection issues for SQL Server using only a Replace as prevention?

I know that dynamic SQL queries are bad due to the SQL Injection issues (as well as performance and other issues). I also know that parameterized queries are prefered to avoid injection issues, we all know that.
But my client is still very stubborn and thinks that just
var UserName=Request.Form["UserName"];
UserName=UserName.Replace("'","''");
SQL="SELECT * FROM Users where UserName='" + UserName + "'";
Is enought protection against SQL injection issues against (SQL Server (Only), not mysql).
Can anyone give me real SQL Injection attack example that still can get through the Replace case above? Guess there's some unicode character issues?
I want some real live examples of attacks that still can get through that simple replace.
My question is only for SQL Server and I know that MySQL has some issues with the \ character.
This will not work if you are using NUMBERs.
"SELECT * FROM data WHERE id = " + a_variable + ";"
using
1;DROP TABLE users
Gives you
SELECT * FROM DATA WHERE id=1;DROP TABLE users;
Have a look at
SQL injection
MSDN SQL Injection
EDIT
Have a look at this. It is very close to your question
Proving SQL Injection
Please input your age : 21; drop table users;
SELECT * FROM table where age = 21; drop table users;
ouchies
I have some trouble understanding the scope of replacement. Your original line is:
SQL=SQL.Replace("''","'");
Because you apply it to the variable name SQL, I would assume you are replacing all occurrences of '' with ' in the entire statement.
This can't be correct: consider this statement:
SELECT * FROM tab WHERE col = '<input value goes here>'
Now, if is the empty string, the statement will be:
SELECT * FROM tab WHERE col = ''
...and after SQL.Replace("''", "'") it will become:
SELECT * FROM tab WHERE col = '
As you can see, it will leave a dangling single quote, and yields a syntax error.
Now, let's suppose you intended to write SQL.Replace("'", "''") then the replaced statement would become:
SELECT * FROM tab WHERE col = ''''
Although syntactically correct, you are now comparing col to a literal single quote (as the '' inside the outer single quotes that delimit the literal string will evaluate to a literal single quote). So this can't be right either.
This leads me to believe that you might be doing something like this:
SQL = "SELECT * FROM tab WHERE col = '" & ParamValue.Replace("'", "''") & "'"
Now, as was already pointed out by the previous poster, this approach does not work for number. Or actually, this approach is only applicable in case you want to process the input inside a string literal in the SQL stament.
There is at least on case where this may be problematic. If MS SQL servers QUOTED_IDENTIFIER setting is disabled, then literal strings may also be enclosed by double quote characters. In this case, user values injecting a double quote will lead to the same problems as you have with single quote strings. In addition, the standard escape sequence for a single quote (two single quotes) doesn't work anymore!!
Just consider this snippet:
SET QUOTED_IDENTIFIER OFF
SELECT " "" '' "
This gives the result:
" ''
So at least, the escaping process must be different depending on whether you delimit strings with single or with double quotes. This may not seem a big problem as QUOTED_IDENTIFIER is ON by default, but still. See:
http://msdn.microsoft.com/en-us/library/ms174393.aspx
Please see this XKCD cartoon:
Little Bobby Tables
The answers so far have been targeting on condition query with numeric datatypes and not having single quote in the WHERE clause.
However in MSSQL *at least in ver 2005), this works even if id is say an integer type:
"SELECT * FROM data WHERE id = '" + a_variable + "';"
I hate to say this but unless stored procedure (code that calls EXECUTE, EXEC, or sp_executesql) is used or WHERE clauses do not use quotes for numeric types, using single quote replacement will almost prevent possibility of SQL Injection. I cannot be 100% certain, and I really hope someone can prove me wrong.
I mentioned stored procedure due to second level injection which I only recently read about. See an SO post here on What is second level SQL Injection.
To quote from the accepted answer of the SO question "Proving SQL Injection":
[...] there is nothing inherently unsafe in a properly-quoted SQL statement.
So, if
String data is properly escaped using Replace("'","''") (and your SQL uses single quotes around strings, see Roland's answer w.r.t. QUOTED_IDENTIFIER),
numeric data comes from numeric variables and is properly (i.e. culture-invariantly) converted to string, and
datetime data comes from datetime variables and is properly converted to string (i.e. into one of the culture-invariant formats accepted by SQL Server).
then I cannot think of any way that SQL injection could be done in SQL Server.
The Unicode thing you mentioned in your question was a MySQL bug. Accounting for such problems in your code provides an extra layer of security (which is usually a good thing). Primarily, it's the task of the database engine to make sure that a properly-quoted SQL statement is not a security risk.
Your client is correct.
SQL = SQL.Replace("'","''");
will stop all injection attacks.
The reason this is not considered safe is that it's easy to miss one string entirely.

SQL Server Escape an Underscore

How do I escape the underscore character?
I am writing something like the following where clause and want to be able to find actual entries with _d at the end.
Where Username Like '%_d'
T-SQL Reference for LIKE:
You can use the wildcard pattern matching characters as literal characters. To use a wildcard character as a literal character, enclose the wildcard character in brackets. The following table shows several examples of using the LIKE keyword and the [ ] wildcard characters.
For your case:
... LIKE '%[_]d'
Obviously #Lasse solution is right, but there's another way to solve your problem: T-SQL operator LIKE defines the optional ESCAPE clause, that lets you declare a character which will escape the next character into the pattern.
For your case, the following WHERE clauses are equivalent:
WHERE username LIKE '%[_]d'; -- #Lasse solution
WHERE username LIKE '%$_d' ESCAPE '$';
WHERE username LIKE '%^_d' ESCAPE '^';
These solutions totally make sense. Unfortunately, neither worked for me as expected. Instead of trying to hassle with it, I went with a work around:
select *
from information_schema.columns
where replace(table_name,'_','!') not like '%!%'
order by table_name
I had a similar issue using like pattern '%_%' did not work - as the question indicates :-)
Using '%\_%' did not work either as this first \ is interpreted "before the like".
Using '%\\_%' works. The \\ (double backslash) is first converted to single \ (backslash) and then used in the like pattern.
Adding [ ] did the job for me
like '%[\\_]%'
This worked for me, just use the escape
'%\_%'
None of these worked for me in SSIS v18.0, so I would up doing something like this:
WHERE CHARINDEX('_', thingyoursearching) < 1..where I am trying to ignore strings with an underscore in them. If you want to find things that have an underscore, just flip it around:
WHERE CHARINDEX('_', thingyoursearching) > 0
Adding to Gerardo Lima's answer, I was having problems when trying to use backslash as my escape character for the ESCAPE clause. This caused issues:
SELECT * FROM table WHERE email LIKE '%#%\_%' ESCAPE '\'
It was resolved by switching to an exclamation point. This worked:
SELECT * FROM table WHERE email LIKE '%#%!_%' ESCAPE '!'

Resources