This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Correct way to escape input data before passing to ODBC
the error I am getting from querying a ODBC query is this:
(pos: 72 '...M = 'Owen O'^Donavon' AND...') - syntax error
and when I try to escape it:
(pos: 73 '... = 'Owen O\'^Donavon' AND...') - syntax error
the ^ means that is where it is breaking
I have tried the following:
NAM = '".$var."'
And also this:
NAM = '".mysql_escape_string($var)."'
then I got desperate
NAM = \"".$var."\"
Where $var is any name that contains a ' in it.
if you need the whole query:
UPDATE TABLE SET COLUMN1 = 'ERR' WHERE COLUMN_NAM = '".mysql_escape_string($var)."' AND COLUMN7 = 0");
does anybody know how I can get the quote properly escaped?
To include a single quote within a MySQL string literal (which is delimited by single quotes), use two single quote characters. e.g.
'I don''t like it'
Effectively, When MySQL parses that, it will see the two single quote characters, and will interpret that as one single quote within a literal, rather than seeing the "end" of the string literal.
But (as you are finding out) when you have only one single quote in there, the MySQL parser has a hissy fit over it. Consider this example:
'I don't like it'
What the MySQL parser sees there is a string literal, five characters in length, containing 'I don'. Then MySQL sees that literal as being followed by some more tokens that need to be parsed: t like it. The parser does NOT see that as part of a string literal. That previous single quote marked the end of the string literal.
So now, the MySQL parser can't make heads or tails of what t like it is supposed to be. It sees the single quote following these tokens as the beginning of another string literal. (So, you could be very clever about what appears there, and manage to get something that MySQL does understand... and that would probably be even worse.)
(NOTE: this issue isn't specific to ODBC; this affects clients that make use of string literals in MySQL query text.)
One way to avoid this type of problem is to use bind variables in your query text, vs. string literals. (But with MySQL, what's happening anyway, is that escaping, what gets sent to the MySQL server (behind the scenes, so to speak) is a string literal.
Sometimes we DO need to include string literals in our query text, and we shouldn't be required to use bind variables as a workaround. So it's good to know how to "escape" a single quote within a string literal which is enclosed in single quotes.
Related
Is is possible to find a string is escaped twice or not using SQL Query (REGEXP) or using PHP?
Please help me on this. I tried more to find it but I'm not getting it anywhere.
$item = "Zak's Laptop";
$escaped_item = mysql_escape_string($item);
$escaped_item_twice = mysql_escape_string($escaped_item);
Here i need to find out that $escaped_item_twice is escaped twice. by their result string which is stored in db already. (i.e) i already stored some strings in db with double escape. I want to get those things and to use stripslashes() on that data. How can i get that data?
You cannot make a difference. Escaping is nothing more than adding some \s (in this case). It leaves no other trail. You cannot tell whether double escaping occurred or you simply wanted to escape an escape character (\\) that was meant to be there.
I was reading Does $_SESSION['username'] need to be escaped before getting into an SQL query? and it said "You need to escape every string you pass to the sql query, regardless of its origin". Now I know something like this is really basic. A Google search turned up over 20, 000 results. Stackoverflow alone had 20 pages of results but no one actually explains what escaping a string is or how to do it. It is just assumed. Can you help me? I want to learn because as always I am making a web app in PHP.
I have looked at:
Inserting Escape Characters, What are all the escape characters in Java?,
Cant escape a string with addcslashes(),
Escape character,
what does mysql_real_escape_string() really do?,
How can i escape double quotes from a string in php?,
MySQL_real_escape_string not adding slashes?,
remove escape sequences from string in php I could go on but I am sure you get the point. This is not laziness.
Escaping a string means to reduce ambiguity in quotes (and other characters) used in that string. For instance, when you're defining a string, you typically surround it in either double quotes or single quotes:
"Hello World."
But what if my string had double quotes within it?
"Hello "World.""
Now I have ambiguity - the interpreter doesn't know where my string ends. If I want to keep my double quotes, I have a couple options. I could use single quotes around my string:
'Hello "World."'
Or I can escape my quotes:
"Hello \"World.\""
Any quote that is preceded by a slash is escaped, and understood to be part of the value of the string.
When it comes to queries, MySQL has certain keywords it watches for that we cannot use in our queries without causing some confusion. Suppose we had a table of values where a column was named "Select", and we wanted to select that:
SELECT select FROM myTable
We've now introduced some ambiguity into our query. Within our query, we can reduce that ambiguity by using back-ticks:
SELECT `select` FROM myTable
This removes the confusion we've introduced by using poor judgment in selecting field names.
A lot of this can be handled for you by simply passing your values through mysql_real_escape_string(). In the example below you can see that we're passing user-submitted data through this function to ensure it won't cause any problems for our query:
// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
Other methods exist for escaping strings, such as add_slashes, addcslashes, quotemeta, and more, though you'll find that when the goal is to run a safe query, by and large developers prefer mysql_real_escape_string or pg_escape_string (in the context of PostgreSQL.
Some characters have special meaning to the SQL database you are using. When these characters are being used in a query they can cause unexpected and/or unintended behavior including allowing an attacker to compromise your database. To prevent these characters from affecting a query in this way they need to be escaped, or to say it a different way, the database needs to be told to not treat them as special characters in this query.
In the case of mysql_real_escape_string() it escapes \x00, \n, \r,\, ', " and \x1a as these, when not escaped, can cause the previously mentioned problems which includes SQL injections with a MySQL database.
For simplicity, you could basically imagine the backslash "\" to be a command to the interpreter during runtime.
For e.g. while interpreting this statement:
$txt = "Hello world!";
during the lexical analysis phase ( or when splitting up the statement into individual tokens) these would be the tokens identified
$, txt, =, ", Hello world!, ", and ;
However the backslash within the string will cause an extra set of tokens and is interpreted as a command to do something with the character that immediately follows it :
for e.g.
$txt = "this \" is escaped";
results in the following tokens:
$, txt, =, ", this, \, ", is escaped, ", and ;
the interpreter already knows (or has preset routes it can take) what to do based on the character that succeeds the \ token. So in the case of " it proceeds to treat it as a character and not as the end-of-string command.
In a database, I have some text stored in a field call Description, the value of the string saved in my database is Me\You "R'S'" % and thats how it appears when querying the database command line.
Now, on a web page i have a function which searches this field as such:
WHERE Description LIKE '%$searchstring%'
So when $searchstring has been cleaned, if i was searching for Me\You, the backslash gets escape and my query reads:
WHERE Description LIKE '%Me\\You%'
However it doesn't return anything.
Strange part of this, is that when i search Me\\You or Me\\\You (So two or three backslashes, but no less or no more) it will return the result i expect with one backslash.
When querying for the result command-line, it does not return a result for:
WHERE Description LIKE '%Me\You%'
or when i use two or three backslashes.
However it will return the result if i use 4 - 7 backslashes, for example:
WHERE Description LIKE '%Me\\\\\\\You%'
will return the string which is Me\You "R'S'" %
Anyone have a reason to this happening? Thanks
Note
Because MySQL uses C escape syntax in strings (for example, “\n” to represent a newline character), you must double any “\” that you use in LIKE strings. For example, to search for “\n”, specify it as “\\n”. To search for “\”, specify it as “\\\\”; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against.
Source: http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html#operator_like
Read this Need to select only data that contains backslashes in MySQL to see how to use double backslash escaping. You could also run MySQL in NO_BACKSLASH_ESCAPES mode (http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_no_backslash_escapes)
Although an old post, you can bypass this limitation using replace function to change backslash to another character: something like this in the WHERE clause. EXAMPLE:
WHERE replace('your field here', '\', '-') like "You-Me%"
I have built a search engine using php and mysql.
Problem:
When I submit a word with an apostrophe in it and return the value to the text field using $_GET the apostrophe has been replaced with a backslash and all characters after the apostrophe are missing.
Example:
Submitted Words: Just can't get enough
Returned Value (Using $_GET): Just can\
Also the url comes up like this:search=just+can%27t+get+enough
As you can see the ' has been replaced with a \ and get enough is missing.
Question:
Does anybody know what causes this to happen and what is the solution to fix this problem?
The code:
http://tinypaste.com/11d62
If you're running PHP version less than 5.3.0, the slash might be added by the Magic Quotes which you can turn off in the .ini file.
From your description of "value to the text field" I speculate you have some output code like this:
Redisplay
<input value='<?=$_GET['search']?>'>
In that case the contained single quote will terminate the html attribute. And anything behind the single quote is simply garbage to the browser. In this case applying htmlspecialchars to the output helps.
(The backslash is likely due to magic_quotes or mysql_*_escape before outputting the text. I doubt the question describes a database error here.)
Update: It seems it's indeed an output problem here:
echo "<a href='searchmusic.php?search=$search&s=$next'>Next</a>";
Regardless of if you use single or double quotes you would need:
echo "<a href='searchmusic.php?search="
. htmlspecialchars(stripslashes($search))
. "&s=$next'>Next</a>";
(Notice that using stripslashes is a workaround here. You should preserve the original search text, or disable the magic_quotes rather.)
Okay I forgot something crucial. htmlspecialchars needs the ENT_QUOTES parameter - always, and in your case particularly:
// prepare for later output:
$search = $_GET['search'];
$html_search = htmlspecialchars(stripslashes($search), ENT_QUOTES);
And then use that whereever you wanted to display $search before:
echo "<a href='searchmusic.php?search=$html_search&s=$next'>Next</a>";
Single quotes are important in PHP and MySQL.
A single quote is a delimeter for a string in PHP, for example:
$str = 'my string';
If you want to include a literal quote inside a string you must tell PHP that the quote is not the end of the string. It is escaped with the backslash, for example:
$str = 'my string with a quote \' inside it';
See PHP Strings for more on this.
MySQL operates in a similar way. An example query might be:
$username = 'andyb';
$quert = "SELECT * FROM users WHERE user_name = '$username'";
The single quote delimits the string parameter. If the $username included a single quote, this would cause the query to end prematurely. Correctly escaping parameters is an important concept to be familiar with as it is one attack vector for breaking into a database - see SQL Injection for more information.
One way to handle this escaping is with mysql_real_escape_string().
I am trying to store regular expression search and substitution strings in a database. At runtime, I read the database, placing the strings into arrays, and then use the PHP preg_replace() method to update large strings written by users with fixes that my client wants.
Here is a sample string pair I am using:
Search string: /([^\r\n+])(\[url)/i
Substitute string: $1\n\n$2
If I place the string in code like this:
preg_replace("/([^\r\n]+)(\[url)/i", "$1\r\n\r\n$2", ProcessString);
Everything works beautifully. This finds instances of a bbCode tag "[url" that does not have a carriage-return/linefeed combination directly in front of it and places that in front of the "[url" tag.
However, when I run the code as I stated using strings from the database (MySql), the "\r\n\r\n" print literals instead of actually creating carriage-return line feeds. The strings are displayed in a "textarea" tag in HTML.
I have looked at the difference between single and quoted strings and my problem would seem to be this, I am assuming? Thinking that the problem is that the strings coming from the database or inserted into the array I'm looping through are created as single-quoted strings, I tried this:
preg_replace($findKey, "{$replaceValue}", ProcessString);
Where $replaceValue = the string '$1\r\n\r\n$2' (again, I am assuming that reading from the database and/or placing the value into an array (mysql_fetch_assoc($result)) is placing the string value into a single-quoted string and therefore the escaped characters are printing as literals instead of the characters the escaped characters actually represent. However, this did not work.
Here is the code I'm using to insert into the database:
INSERT INTO ISG_TCS_Replacements (FindPhrase, ReplacePhrase, ReplacementGroupID, Description, IsRegEx, IsActive, ProcessGroup, ProcessSequence)
VALUES ("/([^\\r\\n]+)(\\[url)/i","$1\\r\\n\\r\\n$2", 0, "Add a new line after [url] tags that are not on a new line currently.", 1, 1, 0, 1);
The fields are varchar(100).
The issue is that \r\n escapes only work in double quoted strings.
print "\r\n";
Whereas your database usage is likely akin to:
$replaceValue = '\r\n';
print "{$replaceValue}"; // uses the literal character string
You are inserting your replacement string with single quotes into the DB. Otherwise you would get the the actual linebreaks back. Mysql does escape them while inserting, but you always get the original string data back.
Reading from a MySQL TEXT/CHAR column is no different than reading from files really. Check your database with mysqladmin, if you see the literal \r\n then there is your problem.
(A literal '\r\n' btw works in the regex, but not in the replacement string.)
Something else. ([^\r\n+]) is probably meant to be ([^\r\n]+). The quantifier must be outside of the character class.