
Originally Posted by
dbevfat
Well, that is obvious, isn't it?
But if a certain value is supposed to come in, and is expected to hold an int, you're going to cast it, right? And if someone send string "12 or 25" instead of an int, you're obviosly casting a string to int.
My personal opinion is that the DB code/queries shouldn't care what the user
input was, or how it was sent, etc.

Originally Posted by
KTottE
Originally Posted by KTottE
SQL injection is a result of not validating input and/or not doing runtime type checks.

Originally Posted by
stereofrog
I have to disargee. Injection problem has absolutely nothing to do with validation. That is, 'valid' data can cause an injection, and vice versa.
I agree with sterefrog. Input validation and protecting your DB from
SQL injection are two different things. Or they should at least be looked
at as two different things.
I separate my DB code into DAOs from the rest of the app so that validating
input from the _REQUEST variables isn't even an issue. I don't see
it as the DB layer's responsibility.
Here's a partial example of one of my DAOs:
PHP Code:
<?php
class CampaignsDao_Mysql extends CampaignsDao {
function CampaignsDao_Mysql($dbConn)
{
parent::CampaignsDao($dbConn);
}
function addCampaign( $name, $groupID, $pay_per_x_visits,
$cost_per_x_visits, $redirect_url=null )
{
if (!strlen($name) )
{
$msg = 'Must provide campaign name as first parameter to '. 'CampaignsDao_Mysql::addCampaign.';
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
elseif (!strlen($groupID))
{
$msg = 'Must provide a group ID as second '.
'parameter to CampaignsDao_Mysql::addCampaign.';
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
elseif (!is_int($pay_per_x_visits) )
{
$msg = 'Must provide an int value as third '.
'parameter to CampaignsDao_Mysql::addCampaign.';
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
elseif (!is_numeric($cost_per_x_visits) )
{
$msg = 'Must provide a numeric value as fourth '.
'parameter to CampaignsDao_Mysql::addCampaign.';
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
// It doesn't necessarily have to be passed in as a float,
// but the DB stores it as a float.
$cost_per_x_visits = (float)$cost_per_x_visits;
$name = mysql_real_escape_string($name, $this->_dbConn);
// $groupID is an alphanumeric string with length of 12
$groupID = mysql_real_escape_string($groupID, $this->_dbConn);
if ($redirect_url !== null)
{
$redirect_url =
mysql_real_escape_string($redirect_url, $this->_dbConn);
}
$campaignsTable = $this->_campaignsTable;
$campaignID = parent::_get_rand_id(12);
$query = "
INSERT INTO $campaignsTable
VALUES ('$campaignID', '$name', $pay_per_x_visits,
$cost_per_x_visits, '$redirect_url') ";
if (!$result = mysql_query($query, $this->_dbConn) )
{
$msg = 'Error adding campaign in '.
'CampaignsDao_Mysql::addCampaign : '.
mysql_error();
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
$joinTable = $this->_campaignsGroupsJoinTable;
$query2 = "
INSERT INTO $joinTable
VALUES ('$groupID', '$campaignID') ";
if (!$result2 = mysql_query($query2, $this->_dbConn) )
{
$msg = 'Error adding campaign in '.
'CampaignsDao_Mysql::addCampaign : '.
mysql_error();
return new DE_DataResourceError($msg, __LINE__, __FILE__);
}
return $campaignID;
}
}
?>
Now I do some validation here, but really, the data should of been checked
before the method call was made. Just like any other method/function call, you have to make sure you feed it the values it wants.
I don't really see it as the DB layer's job
to validate data from the HTTP request. In terms of validation, the DB layer
only really needs to do what's necessary to do its job and protect itself.
It shouldn't really care what the application considers to be "valid" data. So if "12 or 25" is passed in when it is
supposed to be an int value, it shouldn't have even made it
to the point in your code that constructs a query string. So I guess my
point is, that input validation and SQL injection protection are two
different issues(as Stereofrog suggested earlier, you shouldn't confuse them) that should not be mixed together. Once you start looking
at them as the same issue, then you're data storage layer is having
too much influence over what your application code looks like.
--ed
Bookmarks