How to block SQL injection for this query? - sql-injection

now i have this form post script
<?
if(isset($_POST['baslik'])) {
$sql = "INSERT INTO yazilar (baslik, spot, spot_kisa, spot_resim, spot_resim_isim, icerik, kategori, tiklanma, eklemetarihi)
VALUES
('$_POST[baslik]','$_POST[spot]','$_POST[spot_kisa]','$_POST[spot_resim]','$_POST[spot_resim_isim]','$_POST[icerik]','$_POST[kategori]','$_POST[tiklanma]','$_POST[tarih]')";
$sonuc = mysql_query($sql) or die(mysql_error());
if ($sonuc) {
echo ("<p class='msg done'>Yeni icerik basarili bir sekilde eklendi.</p>");
exit;
}
else {
$error = "<p class='msg warning'>Ekleme basarisiz oldu.</p>";
}
}
?>
how can i ignore sql injections for this query?

Use parametrised queries. Unfortunately these are not supported by the mysql extension in PHP 4, but if you are using PHP 5, you can use the mysqli extension or PDO instead, where they are.
See http://www.php.net/manual/en/mysqli.prepare.php for an example of how this is done.

Using parametrised queries as jammycackes suggests is the way to go, but if you for some reason cannot use them then you can use the mysql-real-escape-string function to block most (all?) dangerous values. The problem is that you must use it on every received value, so you cannot use the shorthand notion you use in your example.

Related

Check if pg_prepare was already executed

Is there a way to check if pg_prepare already executed and remove it from the session?
Seems like pg_close doesn't remove prepared statement from the session. Kind of seems like a bug in php, but maybe I'm missing something or maybe there is a workaround.
public static function readSubdomains($dcName, $filter = null) {
// ...
$conn = pg_pconnect($connectionString);
// ...
$result = pg_prepare($conn, "subdomains", "SELECT subdomain
from tenants
where $where
order by 1 asc
");
$result = pg_execute($conn, "subdomains", $params);
// ...
pg_close($conn);
}
Second call to readSubdomains shows a warning like this:
Warning: pg_prepare(): Query failed: ERROR: prepared expression "subdomains" already exists in inc/TestHelper.php on line 121
Always check the official manuals for this sort of stuff.
https://www.postgresql.org/docs/current/view-pg-prepared-statements.html
Oh - if pg_close isn't dropping prepared statements then it isn't closing the connection. You might have some connection pooling involved.

WHERE IN sql query using Zend_Db

Zend Framework beginner here. I'm trying to fetch all the Xbox titles of a video game database. One table contains games. Another table contains game types (ie. Xbox, Xbox Live Arcade, ...). I normally use the following query to get the Xbox titles.
How can I execute the same query using Zend_Db?
Thanks,
SELECT titleGame
FROM Game
WHERE idGameType IN (
SELECT idGameType
FROM GameType
WHERE nameGameType = 'Xbox')
That could be rewritten in Zend Framework a few ways. Here is the way I typically write selects like that using Zend_Db_Table_Select.
<?php
// For brevity, $dbTable = a Zend_Db_Table object
// first construct the subquery/join for the IN clause
// SELECT idGameType FROM GameType HERE nameGameType = 'Xbox'
$subselect = $dbTable->select()
->from('GameType', array('idGameType'))
->where('nameGameType = ?', 'Xbox'); // quotes Xbox appropriately, prevents SQL injection and errors
// construct the primary select
// SELECT titleGame FROM Game WHERE idGameType IN (subquery)
$select = $dbTable->select()
->setIntegrityCheck(false) // allows us to select from another table
->from($dbTable, array('titleGame'))
->where('idGameType IN (?)', $subselect);
$results = $select->query()->fetchAll(); // will throw an exception if the query fails
if(0 === count($results)) {
echo "No Results";
}else{
foreach($results as $result){
echo $result['titleGame'] . '<br />';
}
}
You can also write the SQL as a string, but when possible, the object-oriented approach is ideal because it makes the queries more portable, and most importantly makes it very easy to secure your queries.
Example:
$db = Zend_Db_Table::getDefaultAdapter(); // get the default Db connection
$db->select("select * from table where id = 3"); // doable, but not recommended
You can also create a prepared statement through Zend_Db_Statement to PHP's PDO extension.
$sql = 'SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?';
$stmt = new Zend_Db_Statement_Mysqli($db, $sql);
$stmt->execute(array('goofy', 'FIXED'));
The first approach, the object oriented fluent interface is what you will see the most, and the method I would recommend starting out with and using.
Read through the Zend_Db Manual Pages, and in particular, Zend_Db_Table_Select, Zend_Db_Table, and Zend_Db_Adapter for more information. Even a quick read through over the ZF Quickstart paying specific attention to the Db portion is helpful. It will show how to set up table classes to be a gateway between your application and the database.
SELECT titleGame FROM Game
LEFT JOIN GameType ON GameType.idGameType = Game.idGameType
WHERE GameType.nameGameType = 'Xbox'
Why not use a join instead? From my experience a subselect inside of IN is very slow in MySQL.
$select = $db->select();
$select->from('Game', array('titleGame'));
$select->joinLeft('GameType', 'GameType.idGameType = Game.idGameType', array());
$select->where("GameType.nameGameType = 'Xbox'");

It is possible to execute MySQLi prepared statement before the other one is closed?

Lets say I have a prepared statement. The query that it prepares doesn't matter. I fetch the result like above (I can't show actual code, as it is something I don't want to show off. Please concentrate on the problem, not the examples meaningless) and I get
Fatal error: Call to a member function bind_param() on a non-object in... error. The error caused in the called object.
<?php
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
class table2Info{
private $mysqli;
public function __construct($_mysqli){
$this->mysqli = $_mysqli;
}
public function getInfo($id)
{
$db = $this->mysqli->prepare('SELECT info FROM table2 WHERE id = ? LIMIT 1');
$db->bind_param('i',$db_id);
$db_id = $id;
$db->bind_result($info);
$db->execute();
$db->fetch();
$db->close();
return $info;
}
}
$t2I = new table2Info($mysqli);
$stmt->prepare('SELECT id FROM table1 WHERE name = ?');
$stmt->bind_param('s',$name);
$name = $_GET['name'];
$stmt->bind_result($id);
$stmt->execute();
while($stmt->fetch())
{
//This will cause the fatal-error
echo $t2I->getInfo($id);
}
$stmt->close();
?>
The question is: is there a way to do another prepared statement while another one is still open? It would simplify the code for me. I can't solve this with SQL JOIN or something like that, it must be this way. Now I collect the fetched data in an array and loop through it after $stmt->close(); but that just isn't good solution. Why should I do two loops when one is better?
From the error you're getting it appears that your statement preparation failed. mysqli::prepare returns a MySQLi_STMT object or false on failure.
Check for the return value from your statement preparation that is causing the error. If it is false you can see more details by looking at mysqli::error.

zend framework 1.11.5 is choking on search function - mysql db

ZF 1.11.5 is puking all over this search function. i've tried creating the query several different ways, sent the sql statement to my view, copied and pasted the sql statement into phpMyAdmin and successfully retrieved records using the sql that ZF is choking on. i have been getting a coupld of different errors: 1) an odd SQL error about 'ordinality' (from my Googling ... it seems this is a ZF hang up .. maybe?) and 2) Fatal error: Call to undefined method Application_Model_DbTable_Blah::query() in /blah/blah/blah.php on line blah
public function searchAction($page=1)
{
$searchForm = new Application_Model_FormIndexSearch();
$this->view->searchForm = $searchForm;
$this->view->postValid = '<p>Enter keywords to search the course listings</p>';
$searchTerm = trim( $this->_request->getPost('keywords') );
$searchDb = new Application_Model_DbTable_Ceres();
$selectSql = "SELECT * FROM listings WHERE `s_coursedesc` LIKE '%".$searchTerm."%' || `s_title` LIKE '%".$searchTerm."%'";
$selectQuery = $searchDb->query($selectSql);
$searchResults = $selectQuery->fetchAll();
}
here's my model ....
class Application_Model_DbTable_Ceres extends Zend_Db_Table_Abstract
{
protected $_name = 'listings';
function getCourse( $courseId )
{
$courseid = (int)$courseId;
$row = $this->fetchRow('id=?',$courseId);
if (!$row)
throw new Exception('That course id was not found');
return $row->toArray();
}
}
never mind the view file ... that never throws an error. on a side note: i'm seriously considering kicking ZF to the curb and using CodeIgniter instead.
looking forward to reading your thoughts. thanks ( in advance ) for your responses
You're trying to all a method called query() on Zend_Db_Table but no such method exists. Since you have built the SQL already you might find it easier to call the query on the DB adapter directly, so:
$selectSql = "SELECT * FROM listings WHERE `s_coursedesc` LIKE '%".$searchTerm."%' || `s_title` LIKE '%".$searchTerm."%'";
$searchResults = $selectQuery->getAdapter()->fetchAll($selectSql);
but note that this will give you arrays of data in the result instead of objects which you might be expecting. You also need to escape $searchTerm here since you are getting that value directly from POST data.
Alternatively, you could form the query programatically, something like:
$searchTerm = '%'.$searchTerm.'%';
$select = $selectQuery->select();
$select->where('s_coursedesc LIKE ?', $searchTerm)
->orWhere('s_title LIKE ?', $searchTerm);
$searchResults = $searchQuery->fetchAll($select);

How should I treat strings of digits in XML::RPC and Drupal?

I am trying to use an XML-RPC server on my Drupal (PHP) backend to make it easier for my Perl backend to talk to it. However, I've run into an issue and I'm not sure which parts, if any, are bugs. Essentially, some of the variables I need to pass to Drupal are strings that sometimes are strings full of numbers and the Drupal XML-RPC server is returning an error that when a string is full of numbers it is not properly formed.
My Perl code looks something like this at the moment.
use strict;
use warnings;
use XML::RPC;
use Data::Dumper;
my $xmlrpc = XML::RPC->new(URL);
my $result = $xmlrpc->call( FUNCTION, 'hello world', '9876352345');
print Dumper $result;
The output is:
$VAR1 = {
'faultString' => 'Server error. Invalid method parameters.',
'faultCode' => '-32602'
};
When I have the Drupal XML-RPC server print out the data it receives, I notice that the second argument is typed as i4:
<param>
<value>
<i4>9876352345</i4>
</value>
I think when Drupal then finishes processing the item, it is typing that variable as an int instead of a string. This means when Drupal later tries to check that the variable value is properly formed for a string, the is_string PHP function returns false.
foreach ($signature as $key => $type) {
$arg = $args[$key];
switch ($type) {
case 'int':
case 'i4':
if (is_array($arg) || !is_int($arg)) {
$ok = FALSE;
}
break;
case 'base64':
case 'string':
if (!is_string($arg)) {
$ok = FALSE;
}
break;
case 'boolean':
if ($arg !== FALSE && $arg !== TRUE) {
$ok = FALSE;
}
break;
case 'float':
case 'double':
if (!is_float($arg)) {
$ok = FALSE;
}
break;
case 'date':
case 'dateTime.iso8601':
if (!$arg->is_date) {
$ok = FALSE;
}
break;
}
if (!$ok) {
return xmlrpc_error(-32602, t('Server error. Invalid method parameters.'));
}
}
What I'm not sure about is on which side of the divide the issue lies or if there is something else I should be using. Should the request from the Perl side be typing the content as a string instead of i4 or is the Drupal side of the request too stringent for the string type? My guess is that the issue is the latter, but I don't know enough about how an XML-RPC server is supposed to work to know for sure.
The number 9876352345 is too big to fit in a 32bit integer. That might cause the problem.
are you using frontier? perhaps you could declare the string explicitly?
my $result =
$xmlrpc->call( FUNCTION, 'hello world', $xmlrpc->string('9876352345') );
info from the client docs:
By default, you may pass ordinary Perl values (scalars) to be encoded. RPC2 automatically converts them to XML-RPC types if they look like an integer, float, or as a string. This assumption causes problems when you want to pass a string that looks like "0096", RPC2 will convert that to an because it looks like an integer.
I don't have any experience with the XML::RPC package, but I'm the author of the RPC::XML CPAN module. As with the Frontier package, I provide a way to force a value into a specific type when it would otherwise default to something else.
If I had to guess, I would say that the package you're using simple does a regular-expression match on the data to decide how to type it. I had a similar problem with my package, and given the way Perl handles scalar values the only real way around it is to force it with explicit declaration. As a previous answerer pointed out, the value in question is actually outside the range of the <i4> type (which is a signed 32-bit value). So even if you had intended it to be an integer value, it would have been invalid with regards to the XML-RPC spec.
I would recommend switching to one of the other XML-RPC packages, which have clearer ways of explicitly typing data. According to the docs for XML::RPC, it is possible to force the typing of data, but I found it to be unclear and not very well explained.