mysql_real_escape_string with Zend - php

I am developing a web application using zend framework. For select statements I have used following way.
Ex:
public function getData($name)
{
$sql = "SELECT * from customer where Customer_Name = '$name'";
return $this->objDB->getAdapter()->fetchAll ($sql);
}
This works fine. But If I send customer name as : colvin's place,
The query fail. And I know it's because of the single quote.
Earlier I used addslashes PHP function. But I saw it is not a good way to do this. This time I used mysql_real_escape_string PHP function.
The issue is it says following warning.
Warning</b>: mysql_real_escape_string() [<a href='function.mysql-real-escape-string'>function.mysql-real-escape-string</a>]: Access denied for user 'ODBC'#'localhost' (using password: NO)
This is because of the mysql_real_escape_string function needs a connection to the database opened by mysql_connect. My question is how can I use this with *Zend_DB* classes. I need to use custom select queries always. Appreciate your other suggestions if available.
Thank you

You can use the quote() function provided by Zend_Db:
http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.quoting.quote

You could use parameter binding as well, then the method will look like:
public function getData($name)
{
$sql = "SELECT * from customer where Customer_Name = :name";
return $this->objDB->getAdapter()->fetchAll ($sql, ['name' => $name]);
}
Then your data will be escaped automatically

I had this problem, I used this way and is working correctly:
You can use quote():
The quote() method accepts a single argument, a scalar string value. It returns the value with special characters escaped in a manner appropriate for the RDBMS you are using, and surrounded by string value delimiters. The standard SQL string value delimiter is the single-quote (').
But quote returns a string with 'string' (return it inside quotation), for example I get an string from user from a input-text box (or by URL in GET method)
$string = $this->parameters['string']; // This is like $_POST or $_GET
$string = $this->db->quote($string);
$string = substr($string, 1, strlen($string)-2);
//The above line will remove quotes from start and end of string, you can skip it
Now we can use this $string, and it is like what mysql_real_escape_string returns

I had the same problem and this solution works fine for me. I hope this will help.
you can do something like this:
$quote_removed_name = str_replace("'","''",$name);
then write your query this way:
$sql = "SELECT * from customer where Customer_Name = '$quote_removed_name'";

Related

Protect Oracle database against SQL Injection

I'm on Symfony and I don't know how protect my database against sql injection. If you have some idea, I will be gratefull.
My function with sql :
public function getResult($$value)
{
$sql = "SELECT SOMETHING FROM SOMETHING smt
WHERE smt.THING = '".$value."'";
return $this->egee->executeQuery($sql);
}
And here is my executeQuery funciton :
public function executeQuery($sql) {
$entityManager = $this->em->getConnection('xxx');
$stmt = $entityManager->prepare($sql);
$stmt->execute();
return $stmt->fetch();
}
I allready try with BindParam, but it's didn't work with Oracle.
With BindParam I have this response :
Error 503 : Service Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
Here's how you do it ... with any and every database: parameterized queries.
Your SQL string now becomes:
SELECT SOMETHING FROM SOMETHING smt WHERE smt.THING = ?
Notice the ? (which is not in quotes ... this is not a one-character literal string) This indicates a query parameter.
Now, each time you execute the query, you supply an array() containing each of the parameter-values you want to substitute, in order left-to-right. Different values may be used each time the query is executed (without re-preparing it), because these values are not "part of" the query: they are inputs.
No matter what the parameter-value contains, the database engine will never see it as anything other than the numeric or string value that it is. It will never regard it as "part of the SQL." Thus, SQL-injection becomes impossible.
Furthermore, the [binary] value is used directly, instead of being decoded from a character string. So, say, if you want to use quote-marks as part of your string parameter-value, you would not "encode" them with backslashes. (If you provided \", then "a backslash followed by a quote mark" is what SQL would see as the parameter's value ... a perfectly acceptable two-character value.)
Here's a nice write-up: https://www.w3schools.com/php/php_mysql_prepared_statements.asp
The documentation for Doctrine ORM in the Symfony manual shows an example of using a query parameter:
https://symfony.com/doc/current/doctrine.html#querying-with-sql
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$stmt = $conn->prepare($sql);
$stmt->execute(['price' => $price]);
You don't need to use BindParam. Just pass a hash array to execute(), where the hash keys are the named query parameter placeholders you put in your SQL query.

Variable in Quotes in Postgres Query

This is probably a stupid question, but I have been Googling an answer for the better part of the day and can't get anywhere. I am trying to get the following bit of code to work, but can't find any help on how to properly format a prepared Postgres request in PHP.
$foo = $_GET[bar];
echo $foo; // 5555
//what I'm trying to do:
pg_prepare($dbconn,"table_query","SELECT Members FROM programs WHERE programID = '$1' ");
pg_execute($dbconn,"table_query", array($foo));
If I hardcode the statement with a value, it works fine, but only if I include the single quotes. I've tried just about every method I can find to escape the single quotes or append the quotes to the string, but all I can get are parsing errors.
What totally obvious thing am I missing?
Edit: Changed the snippet to clarify that the variable I am getting does not include quotes. Any method I where I try to add the quotes fails.
Let’s study a complete example. Suppose you got your value from a GET query which set the name pid. From your example query I expect the value to be the decimal representation of an integer, different from zero. It is a string, since nothing else can come from a GET query.
$pid = $_GET['pid'];
// This is _very_ important.
// Anything that comes from outside must be validated or sanitized.
// FILTER_VALIDATE_INT refuses "0" too (correct if needed).
if (filter_var($pid, FILTER_VALIDATE_INT) === false) {
// Deal with invalid input
}
$result = pg_query_params($dbconn,
'SELECT Members FROM programs WHERE programID = $1',
array($pid)
);
pg_query_params binds $1 with $pid and quotes it correctly, while you cannot use double quotes around the statement because PHP would expand $1 incorrectly. There is no need to put quotes around $pid manually, because pg_query_params takes care of this. Furthermore, PostgreSQL accepts an integer value both with quotes and without them, so fumbling with quotes is pointless in this case.
Instead of using the traditional pg_ functions, you might use PDO, the PHP Database Object abstraction layer.
In that case (disregarding possible options needed in your case):
$dsn = 'pgsql:host='. $host .';port=5432;dbname='. $database;
$dbh = new PDO($dsn, $user, $password);
$dbh->prepare('SELECT Members FROM programs WHERE programID = ?');
$result = $dbh->execute(array($pid)); // $pid as before
You should be using prepared statements. This should solve your quoting problem and also remove a major risk of SQL injection. Try something like this:
$stmt = $conn->prepare("SELECT Members FROM programs WHERE programID = ?");
$stmt->bind_param("s", $foo);
$foo = "5555";
$stmt->execute();

Codeigniter using MYSQLI escape string

I am currently updating a section of code that uses mysql currently the escape string is structured like this: $product_name = mysql_real_escape_string(trim($_POST['product_name'])); and works fine.
My issue is when I change the above string to $product_name = mysqli_real_escape_string($database, (trim($_POST['product_name']))); and declare the following: $database = $this->load->database(); above it I get the error that its NULL
How do I escape a string with CI?
CodeIgniter user manual wrote the following.
Beyond simplicity, a major benefit to using the Active Record features is that it allows you >to create database independent applications, since the query syntax is generated by each >database adapter. It also allows for safer queries, since the values are escaped >automatically by the system.
You can use Input class in your controller.
$this->load->model('mymodel');
$something = $this->input->post('something');
$results = $this->mymodel->mymethod($something);
In your model
$this->db->insert('mytable', $data);
You use
$this->db->query("select ?",array("value"));
Where each ? In thee select is the variable you want escaped

Escaping quotes and percentage sign in SQL

I checked similar questions but couldn't find any solution to my particular problem. I have a PHP method that I use as follows:
SELECT * FROM login WHERE userID = 10 //To get this
$result = query("SELECT * FROM login WHERE userID = '%d' ", $userID) //I use this
so the character set '%d' is replaced by what I post in the $userID and the result is returned as JSON. Now i am trying to use it for a search function using.
select * from login where userName like '%searchString%' //Now to get this
$result = query("SELECT * FROM login WHERE userName LIKE '%'%s'%'", $username) // I am trying this
However I got error probably due to not escaping strings properly. Is it possible for any of you to solve this with given information?
Thanks
arda
You also need to change the where clause to use LIKE instead of =
$result = query("select * from login where userName like '%%s%'", $username)
I'm assuming your query method will search/replace the %s with the value of $username.One thing to be mindful is that using "select *" results in an inefficient query execution plan, you should change the * to a list of the columns from the table you want to retrieve. Also, be mindful of SQL injection attacks. See this link http://en.wikipedia.org/wiki/SQL_injection.
you may try by changing this '%'%s'%'
select * from login where userName like '%searchString%' //Now to get this
$username=mysql_real_escape_string($username);
$result = query("SELECT * FROM login WHERE userName = '%%s%'", $username) // I am trying this
I found the solution to be easier than I thought. I simply passed %searchString% as an argument instead of plain searchString
Escaping quotes and escaping percentage signs are two different matters.
First the quotes. The bad way is to "quote the quotes", ie replace all single quotes with two single quotes. It works, but there are disadvantages. The better way is to use query parameters. I don't work with php so I don't know all the details, but I read a lot of comments and answers here on StackOverflow telling php users to use prepared statements. They may or may not escape quotes. My guess is that they do.
For percentage signs, you have to surround them with square brackets to keep them from being treated as wild cards. For example, if your where clause is:
where somefield like '75%'
and you want it to return
75% of bus passengers like singing
but not return
75 bottles of beer on the wall
then your where clause has to be:
where somefield like '75[%]%'

Executing a prepared PDO statement with the like clause [duplicate]

This question already has answers here:
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 3 years ago.
I am new to PHP, and am trying to learn to use PDO to connect to a test MySQL db. I have the following:
try {
$db = new PDO('mysql:dbname=MYDBNAME;host=MYHOST', 'USERNAME', 'PASSWORD');
$query = "select * from books where ? like '%?%'";
$stmt = $db->prepare($query);
$stmt->execute(array($searchtype, $searchterm));
} catch(PDOException $e) {
echo 'PDOException: ' . $e->getMessage();
}
When I try it I get the following warning:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
When I remove the like clause, and the $searchterm param, it returns the result properly. I thought -- like '%?%' -- might not be a legal way to create this query under double quotes, so I tried escaping ', which did not work. I looked around for a solution, and found that someone moved '% and %' down to where $searchterm is:
$query = "select * from books where ? like ?";
...
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\''));
I got the same result.
Any help is appreciated. Thanks!
/ UPDATE ****/
I found on example 12 of http://us3.php.net/manual/en/pdo.prepared-statements.php
Example #12 Invalid use of placeholder
<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name']));
// Below is What they suggest is the correct way.
// placeholder must be used in the place of the whole value
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(array("%$_GET[name]%"));
?>
I tried this, and even though I no longer get a Warning, I do not get any results. However when I execute the query directly I will get a couple of results. Any thoughts?
Don't add the quotes when binding prepared variables and dont bind the column name
$query = sprintf( "select * from books where %s like ?", $searchtype );
...
$stmt->execute(array($searchtype, '%'.$searchterm.'%'));
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\''));
This isn't how parameterised queries work. Inserted parameters act as literal strings already, you don't have to add quote delimiters around them or escape them (that's the whole point), and if you try, you're literally comparing against the string single-quote-searchterm-single-quote.
Consequently if you are (as I suspect) intending to compare a particular column against a literal string, you don't parameterise the column name. At the moment you are comparing a literal string to another literal string, so it'll either always be true or always false regardless of the data in the row!
So I think what you probably mean is:
$query= "SELECT * FROM books WHERE $searchtype LIKE ?";
$like= "%$searchterm%";
$stmt->execute(array($like));
thought naturally you will have to be very careful that $searchtype is known-good to avoid SQL-injection. Typically you would compare it against a list of acceptable column names before using it.
(Aside: there is a way of putting arbitrary strings in a schema name that you can use for a column, but it's annoying, varies across databases and there isn't a standard escaping function for it. In MySQL, you backslash-escape the backquote character, quotes and backslashes and surround the name with backquotes. In ANSI SQL you use double-quotes with doubled-double-quotes inside. In SQL Server you use square brackets. However in reality you vary rarely need to do any of this because really you only ever want to allow a few predefined column names.)
(Another aside: if you want to be able to allow $searchterm values with literal percents, underlines or backslashes in—so users can search for “100%” without matching any string with 100 in—you have to use an explicit escape character, which is a bit tedious:)
$query= "SELECT * FROM books WHERE $searchtype LIKE ? ESCAPE '+'";
$like= str_replace(array('+', '%', '_'), array('++', '+%', '+_'), $searchterm);
$stmt->execute(array("%$like%"));
The problem I see is if you had written a wrapper for PDO, then you would have to somehow handle this separately. The answer I had found and loved was write your query and concat the % to the parameter. i.e. "WHERE column like concat('%', :something, '%')"

Categories