Php on zend, how to escape a variable for a query? - php

im doing some queries in Zend Framework and i need to make sure no SQL injection is possible in the next kind of formats. I can use mysql_escape(deprecated) and wont do all the work. If i try to use real_mysql_escape it wont be able to grab the conection with the database and i cant find how zend_filter would solve the problem.
The query im doing (simplied) have the next sintaxes:
$db = Zend_Registry::get('db');
$select = "SELECT COUNT(*) AS num
FROM message m
WHERE m.message LIKE '".$username." %'";
$row = $db->fetchRow($select);
What is the best way to prevent SQL INJECTION with this framework?

Easy:
$db->quote($username);
So:
$username = $db->quote($username . '%');
$select = 'SELECT COUNT(*) AS num
FROM message m
WHERE m.message LIKE ' . $username;
$row = $db->fetchRow($select);

$sql = 'SELECT * FROM messages WHERE username LIKE ?';
$row = $db->fetchRow($sql, $username);
Reference: http://framework.zend.com/manual/en/zend.db.html

When working with a model you can use:
$bugs = new Bugs();
$row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));

Related

Variable in SQL select

I'm trying to make a search bar with PHP to show the product that we got in store with a get script. Now I want to put the variable I get in my SQL query like this:
$search = $_GET['q'];
$sql = "SELECT
`product`.`productcode`,
`product`.`productnaam`,
`product`.`prijs`,
`product`.`voorraad`,
`afbeelding`.`image_id`,
`afbeelding`.`image_ctgy`
FROM `product`, `afbeelding`
WHERE `product`.`productcode` = `afbeelding`.`image_id` AND `afbeelding`.`image_ctgy` = $search
GROUP BY `productnaam`
ORDER BY `productnaam`;";
How do I make it so the variable doesn't mess with the query?
Take a look at PDO prepared statements.
They allow you to use a variable inside your query without worrying about MySQL injections too much.
$stmt = $dbh->prepare("SELECT
`product`.`productcode`,
`product`.`productnaam`,
`product`.`prijs`,
`product`.`voorraad`,
`afbeelding`.`image_id`,
`afbeelding`.`image_ctgy`
FROM `product`, `afbeelding`
WHERE `product`.`productcode` = `afbeelding`.`image_id` AND `afbeelding`.`image_ctgy` = :search
GROUP BY `productnaam`
ORDER BY `productnaam`");
$stmt->bindParam(':search', $search);
$search = mysqli_real_escape_string($_GET['q']);
$sql = "SELECT product.productcode, product.productnaam, product.prijs, product.voorraad, afbeelding.image_id, afbeelding.image_ctgy FROM product, afbeelding WHERE product.productcode = afbeelding.image_id AND afbeelding.image_ctgy = '" . $search . "' GROUP BY productnaam ORDER BY productnaam";
Or use PDO instead (OOP):
$dbh = new mysqli($servername, $username, $password, $dbname);
$stmt = $dbh->prepare("SELECT product.productcode, product.productnaam, product.prijs, product.voorraad, afbeelding.image_id, afbeelding.image_ctgy FROM product, afbeelding WHERE product.productcode = afbeelding.image_id AND afbeelding.image_ctgy = :search GROUP BY productnaam ORDER BY productnaam");
if ($stmt->execute([':search' => $_GET['q']])) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
If you're using an older version of php, replace [':search' => $_GET['q']] with array(':search' => $_GET['q'])
Use filter_input(). It will make sure the send $_GET variable is a secure string.
In your example:
// q is the name of the $_GET variable.
$search = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS);

Selecting row where field = value error

Can you explain me why my code isnt working? Ive been thinking about it for a while and I cant find it. obviously I want to print some columns from rows where column F1 is equal to user's username.
$db = JFactory::getDBO();
$user = JFactory::getUser();
$query = "SELECT * FROM qwozh_visforms_1 WHERE F1 = ".$user->username;
$db->setQuery($query);
$result = $db->query();
while($row = mysqli_fetch_object($result))
{
print $row->F1;
}
It works when I remove condition from select command and I cant figure out how to make it work with it
$query = "SELECT * FROM qwozh_visforms_1";
Now Im getting this error:
UNKNOWN COLUMN 'ADMIN' IN 'WHERE CLAUSE' SQL=SELECT * FROM
QWOZH_VISFORMS_1 WHERE F1 = ADMIN RETURN TO PREVIOUS PAGE
Thanks
All it takes if a quick read of the Joomla documentation. The following is the same as your query but making full use of Joomla's up to date database class:
$db = JFactory::getDbo();
$user = JFactory::getUser();
$query = $db->getQuery(true);
$query->select(array('*'))
->from($db->quoteName('#__visforms_1'))
->where($db->quoteName('F1') . ' = '. $db->quote($user->username));
$db->setQuery($query);
$results = $db->loadObjectList();
// Display the results
foreach($results as $result){
// echo what you want here
}
Note, I've used the prefix #__ rather than manually defining qwozh, assuming your table belong to a Joomla extension.
I know PHP and MySQL, but not Joomla. But the problem is that your username needs to be quoted because it is probably a string.
Try this:
$query = "SELECT * FROM qwozh_visforms_1 WHERE F1 = '{$user->username}'";
or
$query = "SELECT * FROM qwozh_visforms_1 WHERE F1 = ".$db->quote($user->username);
You need to wrap the name in quotes:
$query = "SELECT * FROM qwozh_visforms_1 WHERE F1 = '".$user->username . "'";
As pointed out in the comments my answer has a pretty bad quality, you may want to look at prepared statements, expecially using bindParam, which takes care of quotes for you and protects you agains SQL injection attacks.
Unfortunately I cannot suggest you Joomla based approach since I never used it, somebody else can suggest you a more appropriate solution.

How WHERE clause works when inserting php variables

I am having problems trying to get these queries with a WHERE clause to work. I have two tables which look like this :
What I am trying to do is return the genre that each film has. At the moment no data is returning at all from what I can see. Here are the two queries:
$film_id = $row_movie_list['film_id'];
mysql_select_db($database_fot , $fot);
$query_get_genre = "SELECT * FROM film_genre WHERE `id_film` ='". $film_id. "'";
$get_genre = mysql_query($query_get_genre, $fot) or die(mysql_error());
$row_get_genre = mysql_fetch_assoc($get_genre);
$totalRows_get_genre = mysql_num_rows($get_genre);
$genre_id = $row_get_genre['id_genre'];
mysql_select_db($database_fot , $fot);
$query_genre = "SELECT * FROM genre WHERE `id_genre` ='". $genre_id. "'";
$genre= mysql_query($query_genre, $fot) or die(mysql_error());
$row__genre = mysql_fetch_assoc($genre);
$totalRows_genre = mysql_num_rows($genre);
PHP with content area. I fairly new to PHP so any help would be appreciated.
<?php do { echo $genre['genre']; } while($row_get_genre = mysql_fetch_assoc($get_genre)); ?>
Update: I am now able to get first genre but not second it just echos the first one twice and I have tried but still no luck:
do {do { echo $row_genre['genre']; } while($row_genre = mysql_fetch_assoc($genre));} while($row_get_genre = mysql_fetch_assoc($get_genre)); ?>
Avoiding the fact that you're using a deprecated way to establish connection and interact with MySQL, what you're doing is getting a single relation genre-film and then getting the row of the genre that matches. You should surround part of your code with a while that executes while it's still genres of the film with id. Something like:
$film_id = $row_movie_list['film_id'];
mysql_select_db($database_fot , $fot);
$query_get_genre = "SELECT * FROM film_genre WHERE `id_film` ='". $film_id. "'";
$get_genre = mysql_query($query_get_genre, $fot) or die(mysql_error());
while($row_get_genre = mysql_fetch_assoc($get_genre)){
$genre_id = $row_get_genre['id_genre'];
$query_genre = "SELECT * FROM genre WHERE `id_genre` ='". $genre_id. "'";
$genre= mysql_query($query_genre, $fot) or die(mysql_error());
$row__genre = mysql_fetch_assoc($genre);
// You should do whatever you want to do with $row__genre here. Otherwise it will be cleared.
}
I must insist this is a deprecated and insecure way of communication with a MySQL Database. I recommend you read about MySQLi or PDO extensions.
MySQLi: http://www.php.net/manual/en/book.mysqli.php
PDO: http://www.php.net/manual/en/book.pdo.php

mysql query fails if name has more then 1 words

I began to create a website for my small real estate business.
I played a bit with functions http://www.php.net mysql and I managed to make a page accessed via AJAX and returning html content for the search engine.
I have a database already populated with apartments and houses
The problem is that if the apartment name is "apartment" I return html content if "apartment with 3 rooms" it no longer write anything.
I do not understand where I was wrong:
<?php
$search = $_GET['selected'];
$link = mysql_connect('localhost', 'root', '');
mysql_select_db('houses', $link);
function searchHouse($search, $link){
$query = "select * from houses where name=$search limit 1";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$query2 = "select * from houses_info where house_id=$row[id]";
$result2 = mysql_query($query2);
$row = mysql_fetch_assoc($result2);
return $row;
}
$result = searchHouse($search, $link);
echo $result['house_sq'];
echo "<br>";
echo $result['house_rooms'];
echo "<br>";
echo $result['house_bathrooms'];
echo "<br>";
echo $result['house_address'];
?>
you should know if you "played" with php.net that mysql_* functions are deprecated and are no longer maintained. It's a red box on top of the page informing you that.
you have a big MySQL injection hole there, you are not escaping $string at all
your problem is that you are not adding quotes to $string like: '$string'
you should stat using PDO to get rid of the bad code and SQL Injections holes.
you can wrap those 2 selects into a single select:
<?php
function searchHouse($search, $link){
$search = mysql_real_escape_string($search);
$query = "select * from houses_info where house_id IN (select * from houses where name='".$search."' limit 1)";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
return $row;
}
?>
since you are already building that website you can start moving to PDO, read this tutorial, your code will be more like this:
<?php
$db = new PDO('mysql:host=localhost;dbname=houses;charset=UTF-8', 'root', '', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$search = $_GET['selected'];
function searchHouse($search){
global $db;
$query = $db->prepare("select * from houses_info where house_id IN (select * from houses where name=:search limit 1)");
$query->execute(array(':search' => $search));
$row = $query->fetch(PDO::FETCH_ASSOC);
return $row;
}
$result = searchHouse($search);
?>
try:
$query = "select * from houses where name='".mysql_real_escape_string($search)."' limit 1";
and remember to always sanitize user input before passing it to sql to avoid sql injections.
Your first query should be:
$query = "select * from houses where name like $search% limit 1";
Strings need to be quoted in queries. Also, this is vulnerable to MySQL injection, make sure to escape $search with mysql_real_escape_string. Or even better yet use MySQLi or PDO instead of the old mysql_ functions.
$query = "select * from houses where name=$search limit 1";
Should be:
$query = "select * from houses where name='$search' limit 1";
Although you REALLY need to escape $search because it came from a user, even if they aren't malicious, any search queries with a single quote in it will break;
$search = $_GET['selected'];
Should be:
$search = mysql_real_escape_string($_GET['selected']);
(Anybody have the copy paste handy with the links to tutorials for MySQLi/PDO and such?)

PHP Patterns - how can I write this code?

I want to make an category-system CMS. Everything is fine, except a big trouble.
How can I can handle and generate the mysql query depends by some inputs like:
site.com/some-category&sortby=views&from=smt&anotherInput=key
For example, for this input my query should be something like
SELECT * FROM `articles` WHERE from='smt' AND afield='key' ORDER BY VIEWS
But these inputs will be different. How I can write this code? I don't know much things about designs patterns, but, I've heard about Factory pattern, is this a part of my solution?
Than
Factory pattern can help you with e.g. connecting/quering various databases without need to rewrite the entire code. This has nothing to do about query itself.
You can look at PDO extension, I usually use it together with prepared statements.
It will let you write queries like this:
$prepare = $db->prepare('
SELECT
*
FROM
articles
WHERE
from=:from AND afield=:afield
ORDER BY
views
');
$prepare->bindValue(':from', $_GET['from'], PDO::PARAM_STR);
$prepare->bindValue(':afield', $_GET['afield'], PDO::PARAM_STR);
$prepare->execute();
return $prepare;
The good thing about it is that you don't need to protect this from sql injections as PDO makes it for you. Also, the query is cached and you can run it several times with different params.
Very bad practice to use raw GET params in query directly, i.e. you shouldn't make constructions like
SELECT * FROM articles WHERE from=$_GET['from'] AND afield='key' ORDER BY VIEWS
but instead something like
if ($_GET['from'] == 'smt') $from = 'smt'
SELECT * FROM articles WHERE from='$from' AND afield='key' ORDER BY VIEWS
and so on
P.S. keyword is 'sql injection'
You can build the query string as pieces depending on what you need:
$query = "SELECT * FROM `articles` WHERE 1 = 1";
$where = ''
if (isset($_GET['from'])) {
$where .= " AND `from` = '" . mysql_real_escape_string($_GET['from']) . "'"
}
if (isset($_GET['anotherInput'])) {
$where .= " AND `from` = '" . mysql_real_escape_string($_GET['anotherInput']) . "'"
}
if (isset($_GET['sortby'] == 'views') {
$orderby = " ORDER BY `views` DESC"
} else {
$orderby = " ORDER BY `id` DESC"
}
$query = $query . $where . $orderby;
$result = mysql_query($query);
This is sort of the straight PHP/MySQL way, but I actually do suggest that you use prepared statements as in Pavel Dubinin's answer.
This has nothing to do with patterns. Use the $_GET superglobal variable to dynamically generate your query string.
$query = "SELECT * FROM articles WHERE from='".
$_GET['from'].
"' AND afield='".
$_GET['anotherInput'].
"' ORDER BY ".
$_GET['sortby'];
Disclaimer: This is prone to SQL injection. Use input escaping and prepared statements, ex PDO, in a production environment like:
$query = "SELECT * FROM articles WHERE from='?' AND afield='?' ORDER BY ?";
$clean_from = htmlentities($_POST['from'], ENT_QUOTES, 'UTF-8');
$clean_anotherInput = htmlentities($_POST['anotherInput'], ENT_QUOTES, 'UTF-8');
$clean_sortby = htmlentities($_POST['sortby'], ENT_QUOTES, 'UTF-8');
$clean_inputs = array($clean_from, $clean_anotherInput, $clean_sortby);
$sth = $dbh->prepare($query);
$sth->execute($clean_inputs);

Categories