How can I escape the # in PHP? When I use it in a query it turns the remaining line of code into a comment. This is what I have right now:
$columns = "head1, #_search, #_stuff";
$result = mysql_query("SELECT $columns from table LIMIT $k,$j");
I can't just put escape # right after $columns since it will just become a comment.
~edit: yes I probably should have copied the code directly, but some of it is confidential and much more complicated.
You should be using quotes for your strings:
$columns = 'head1, #_search, #_stuff';
However, this still doesn't make much sense.
It's also recommended to favour PDO or mysqli over mysql_*
Try adding backslashes
$columns = 'head1, \#_search, \#_stuff';
How about the following ? :
$columns = "head1, `#_search`, `#_stuff`";
You can use `(backtick) to quote reserved words.
If you want to quote table/column name you can do the following example:
SELECT * FROM `#table1` WHERE `#table1`.`#column1` = 1;
Reference
Shouldn't it be a string literal?
$columns = 'head1, #_search, #_stuff'
Related
I have this issue.
I need to receive, from comments column in mysql database, a string like this:
WHERE IDTable=$number
When i get this comment i have to put it like a Where clause in my query.
But if i write this code
$where=getComment($table,$field); //I get the string i wrote above
$number=5; //I initialize $number in my code
$sql="SELECT * FROM table $where";
print "SQL: $sql";
i get this:
SELECT * FROM table WHERE IDTable=$number
obviously i'd like to have in response:
SELECT * FROM table WHERE IDTable=5
How can I do that?
Thanks
I strongly suspect that the code you have a problem with is not the same code as above, as the above would not produce the result you stated. At the very least you are missing the definition of the function you're calling, to create said output.
However, what would produce such a result is by using single quotes around a string. Which prevents variable expansion, and treats them as regular strings instead.
Not only that, but your code is out of order as well. You cannot use a variable before you have declared it, as it simply does not exist yet.
The string returned by getComment() will not be parsed, so any PHP variables in it ($number) will be returned as the literal string.
I can think of two options -
1
Allow an extra parameter for getComment() so you can pass it $number
$number=5;
$where = getComment($table,$field,$number); // returns "WHERE IDTable=5"
$sql="SELECT * FROM table $where";
2
Do not return $number from getComment(), then you can add it when you build the query.
$where=getComment($table,$field); // returns "WHERE IDTable="
$number=5;
$sql="SELECT * FROM table $where $number";
Perhaps the String Value you got from MySQL: WHERE IDTable=$number may have been enclosed within Single Quotes. Consider the Example Below.
$number = 22;
$str = 'WHERE IDTable=$number';
var_dump($str); //<== YIELDS:: 'WHERE IDTable=$number' B'COS IT'S IN SINGLE QUOTES
$parts = explode("=", $str);
list($where, $var) = $parts;
$var = ltrim(trim($var), "\$");
$newStr = trim($where . "=" . $$var);
var_dump($$var); //<== YIELDS:: int 22
var_dump($newStr); //<== YIELDS:: 'WHERE IDTable=22' (length=16)
Assuming this is the case with your String; to get around that, You may simply want to extract the Variable from the String and then rebuild the String as the Snippet above demonstrates. Otherwise; if you have a possibility of enclosing the String in Double Quotes, this convoluted work-around would be utterly irrelevant.
I can't figure out why, but when I run this script, it's only displaying the $row[0] column and not any other columns I put in.
$mlsnum = mysql_real_escape_string($_GET['mlsnum']);
$link = mysql_connect('localhost','user','password');
mysql_select_db('singleprop', $link);
$query = "SELECT 'MSTLISTPRC' FROM jos_mls WHERE MSTMLSNO = '".$mlsnum."';";
$return = mysql_query($query);
$result = mysql_fetch_array($return);
$price = $result['MSTLISTPRC'];
echo $price;
Instead of echoing the value of the column that meets the WHERE criteria, it echoes the column name.
Drop the single quotes. They indicate a literal string.
SELECT MSTLISTPRC ...
A string is a sequence of bytes or characters, enclosed within either single quote (“'”) or double quote (“"”) characters. Examples:
'a string'
"another string"
Documentation
You also need to use an associative array in order to call the column name:
$result = mysql_fetch_assoc($return);
Also, please stop using mysql_ functions. They are no longer maintained and are officially deprecated. See the red box? Learn about prepared statements instead, and use PDO or MySQLi - this article will help you decide which.
remove the quotes around 'MSTLISTPRC' = problem solved
For selecting column you do not use quotes. We use "`" character
change
$query = "SELECT 'MSTLISTPRC' FROM jos_mls WHERE MSTMLSNO = '".$mlsnum."';";
to
$query = "SELECT `MSTLISTPRC` FROM jos_mls WHERE MSTMLSNO = '".$mlsnum."';";
The Gist
I want to perform an SQL query that depends on a variable number of parameters in my GET without being vulnerable to SQL injection.
The Parameters
My URL can be formed like this:
https://www.example.com/index.php?param1=blah1,param2=blah2,param3=a,b,c
or like this:
https://www.example.com/index.php?param1=blah1,param2=blah2,param3=a,b,c,d,e,f,g
In other words, param3 can have a variable number of comma-delimited parameters a,b,c,etc.
The White-list
I check to make sure that all parameters in a,b,c,etc. are in an approved white-list before I perform the query.
// $valid_params is an array of pre-approved parameters.
$arr = explode(',', clean($_GET['param3']));
$params = Array();
foreach($arr as $param){
if(in_array($param, $valid_params)){
array_push($params, $param);
}
}
The Query
I set up my database connection like this (with MySQL):
$db_connection = new PDO("mysql:host={$DB_HOST};dbname={$DB_NAME}",$DB_USER,$DB_PASS);
$db_connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
And I want to perform a query like this (except safely):
$comma_separated_params = implode(',',$params);
$result = $db_connection->query("SELECT {$comma_separated_params} FROM some_table");
The Goal
Does anyone know how I could do this safely and efficiently?
Depending on your concern for overhead, you could just SELECT * and then filter the array in PHP - if the parameter is never sent to the database then there is no room for injection.
However it's not exactly the most elegant solution. Here's how I'd do it:
$comma_separated_params =
implode(
",",
array_map(
function($a) {return "`".$a."`";},
array_intersect(
explode(",",$_GET['param3']),
$valid_params
)
)
)
);
That one-line-wonder (with newlines added for clarity) will take the $_GET['param3'] variable, split it on commas, intersect it with your valid parameters (instead of your foreach loop), wraps each element in backticks (see note below) and finally glues them together with commas.
See, backticks allow you to use literally any string as a field name. Usually it's to allow keywords as names, but it can also allow for column names with spaces, and so on. The only character that has meaning within the backticks are backslashes and backticks - which it is safe to assume are not present since they'd have to be in your list of $valid_params to get this far.
Whitelisting is the way to go here. If you only allow things in that you've already specifically defined you should be okay. As for how efficient, this is all relative. The version you're using will perform well for relatively small lists, such as those with under 100 columns, so I wouldn't worry.
Bonus points for using PDO.
There's a chance your definition of 'allowed' columns and what's actually in the database might diverge. A more relaxed specification might be to grab the fields using SHOW FIELDS for the table in question and only allow those.
If you are only allowing a specific list of predefined values to be passed in param 3, and you are comparing the input values against them, I don;t think you have any injection exposure, as you then have full control over the value that ultimately go into your $comma_seperated_params variable.
This needs some work to finish, but with parameter binding it would look like this:
$binding = array();
$selects = array();
foreach ( $params as $value ) {
$binding[] = ':' . $value;
$selects = '?';
}
$select = implode(',', $select);
$result = $db_connection->prepare("SELECT $select FROM some_table");
foreach ( $binding as $key => $bind ) {
$result->bindParam($key, $bind, PDO::PARAM_STR);
}
$result->execute();
PDO::prepare will help you. This is exactly is recommended by experts. Never use mysql_real_escape_string (string). Always go for prepared statements.
I try to use PDO::quote to escape a string in a LIKE expression, so the user string must not be surrounded like in :
LIKE "%userStringToEscape%"
Is there a way to do that ?
$var = "%userStringToEscape%";
$var = $stmt->quote($var);
$sql = "SELECT * FROM table WHERE field LIKE $var";
same goes for the prepared statements
Use substr($db->quote($var), 1, -1)
Really though, don't. You'll end up with larger problems than the ones you started with.
The clean solution to do this is, of course, $db->quote('%'.$var.'%')
Just do:
$like = $pdo->quote("%{$userStringToEscape}%");
$sql = "SELECT * FROM field LIKE {$like}";
http://php.net/manual/en/pdo.quote.php
I am using this query to input info for front end editing. 2 problems. First, input works fine as number, but will not post text. Second, new_type1 and new_type2 are checkboxes and do not post correctly.
$query = "DELETE p.* FROM #__bl_press as p WHERE p.match_id = ".$row->id;
$db->setQuery($query);
$db->query();
if(isset($_POST['new_source']) && count($_POST['new_source'])){
for ($i=0; $i< count($_POST['new_source']); $i++){
$new_event1 = $_POST['new_source'][$i];
$query = "INSERT INTO #__bl_press(n_source, n_title, n_link, match_id, type1, type2) VALUES(".$new_event1.",".$_POST['new_title'][$i].",".$_POST['new_link'][$i].",".$row->id.",".intval($_POST['new_type1'][$i]).",".intval($_POST['new_type2'][$i]).")";
$db->setQuery($query);
$db->query();
}
}
You need quotes round the string values:
$query = "INSERT INTO #__bl_press(n_source,n_title,n_link,match_id,type1,type2)".
"VALUES('".$new_event1."','".$_POST['new_title'][$i]."','" . // etc
// ^ ^ ^ ^ ^
Also you should use mysql_real_escape_string or parameterized queries to avoid SQL injection vulnerabilities and runtime errors when the posted data contains characters such as quotes or backslashes. See also this question for more information:
Best way to stop SQL Injection in PHP
You're not adding quotes (') around them. A number is just a number but a string has to be written as "string" instead of string.
Also, to avoid SQL injections, always use mysql_real_escape_string or other escaping features.
May be you forgot to use single quote (') for string. Just a silly mistake:
$query = "INSERT INTO #__bl_press(n_source,n_title,n_link,match_id,type1,type2) VALUES('".$new_event1."','".$_POST['new_title'][$i]."','".$_POST['new_link'][$i]."',".$row->id.",'".intval($_POST['new_type1'][$i])."','".intval($_POST['new_type2'][$i])."')";