views:

297

answers:

6

Hi,

i am using a query inside php as

 $query =  'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,1';

where i am trying to insert a php variable instead of 1 in the limit..

   $query =  'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,"'.$_GET['limit'].'"';

but it shows me the error . Pls help me .. THere are some errors in keeping $_GET['limit']..

+4  A: 

Three things:

  1. The way you're writing out those queries is a bit hard to read. Personally I prefer using a multi-line heredoc syntax (as per below) but this isn't strictly required;

  2. Any user input should go through mysql_real_escape_string() to avoid SQL injection attacks. Note: "user input" includes anything that comes from the client including cookies, form fields (normal or hidden), query strings, etc; and

  3. You don't need to quote the second argument to LIMIT clause, which is probably the source of your problem, meaning put LIMIT 0,5 not LIMIT 0,"5".

So try:

$title = mysql_real_escape_string($_GET['title']);
$author = mysql_real_escape_string($_GET['author']);
$limit = (int)$_GET['limit'];

$query = <<<END
SELECT *
FROM #__chronoforms_UploadAuthor
WHERE text_6 LIKE "$title%" 
AND text_7 LIKE "%$author%"
LIMIT 0,$limit
END;

Also, one commentor noted that % and _ should be escaped. That may or may not be true. Many applications allow the user to enter wildcards. If that's the case then you shouldn't escape them. If you must escape them them process them:

$title = like_escape($limit);

function like_escape($str) {
  return preg_replace('!(?|\\)((?:\\)*)([%_])!', '$1\$2', $str);
}

That somewhat complicated regex is trying to stop someone putting in '\%' and getting '\%', which then escape the backslash but not the '%'.

cletus
when using LIKE also escape _ and %
stereofrog
not "user input" but any string value you didn't mention sanitization for the limit parameterand you are only one who use heredoc for the queries.
Col. Shrapnel
@Col 1. **all** GET/POST parameters are "user input" and 2. I don't understand your point about heredocs. So what if no one else does? It doesn't make me wrong or them right.
cletus
not GET/POST parameters , but **any string value** goes to the query.
Col. Shrapnel
@stereofrog: LIKE-escaping is somewhat tricky. If you need to support it, see http://stackoverflow.com/questions/2106207/escape-sql-like-value-for-postgres-with-psycopg2
bobince
I didn't notice you sanitize $limit in the code. I beg my pardon
Col. Shrapnel
@Col clarification added. Happy yet?
cletus
@stereofrog added wildcard escaping.
cletus
nope :) escaping intentded not for the "user input", but for the query content. Source of input doesn't matter. It can be user or server, form or file. it is not "sanitization" but merely syntax rule. 2-step rule: enclose string contents into quotes and escape special characters in it. As a matter of fact, it has no relation to the user input.
Col. Shrapnel
use prepared statements instead of `mysql_real_escape_string` if you do not know 100 % what you are doing (which seems to be the case for the op). `mysql_real_escapey_string` still can cause problems, when used for uncasted number-values
knittl
A: 

This should work:

$query =  'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,'.$_GET['limit'];

But you really should filter incoming data...

$query =  'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.mysql_real_escape_string($_GET['title']).'%" and text_7 like "%'.mysql_real_escape_string($_GET['author']).'%" limit 0,"'.intval($_GET['limit']).'"';
Christoffer
addslashes is not a suffient method to escape mysql injections, using mysql_real_escape_string will help in that topic.
Cem Kalyoncu
`'limit 0,"'.addslashes($_GET['limit']).'"'` still doesn't work either, since the limit can't be a string. It should be `limit 0,'.intval($_GET['limit']).'`
Zarel
+1  A: 

The hash sign (#) starts a comment in SQL, which looks like your problem

Charlie Somerville
But the first one works so I'm assuming that can't be the problem.
cletus
A: 

You've enclosed the $_GET['limit'] in double-quotes, which is the source of the problem.

Try this:

$query =  'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,'.$_GET['limit'];

Also as Cletus mentions in this answer, there are many, more serious problems you need to resolve.

codaddict
A: 

Remove the double-quotes around $_GET['limit']. The two numbers that the LIMIT clause takes should not be quoted.

Kai Chan
+1  A: 

Whant bunch of awful answers!

a. to slove limit problem:

$limit=intval($_GET['limit']); 

and then

...LIMIT 0, $limit

in the query.

b. to sanitize $_GET['title'], as many mentioned:

$title = mysql_real_escape_string($_GET['title']);   

so the final code must be

$limit=intval($_GET['limit']); 
$title = mysql_real_escape_string($_GET['title']);   
$author = mysql_real_escape_string($_GET['author']);   
$query = "SELECT * from #__chronoforms_UploadAuthor 
          WHERE text_6 like '$title' and text_7 like '%$author%' 
          LIMIT 0, $limit";  
Col. Shrapnel