我正在构建一个数据库类,并且认为合并某种形式的SQL注入预防(duh!)是个好主意。下面是运行数据库查询的方法:
class DB
{
var $db_host = 'localhost';
var $db_user = 'root';
var $db_passwd = '';
var $db_name = 'whatever';
function query($sql)
{
$this->result = mysql_query($sql, $this->link);
if(!$this->result)
{
$this->error(mysql_error());
} else {
return $this->result;
}
}
}这门课上还有更多的东西,但我只是为了这个而删掉它。我面临的问题是,如果我只使用mysql_real_escape_string($sql, $this->link);,那么它将转义整个查询并导致SQL语法错误。如何动态查找需要转义的变量?我想避免在我的主代码块中使用mysql_real_escape_string(),我宁愿在函数中使用它。
谢谢。
发布于 2010-03-30 03:44:15
问题是,当您构建一个SQL查询时,要通过查找变量来阻止注入已经太晚了-否则它已经内置到PHP中了。
转义需要在构建查询时更早地完成。您可以使用查询构建类。
然而,我推荐一种不同的方法--那就是有一个提供数据库表作为对象的层,这是一个从base db entity class派生的示例user object,它使用active record pattern和iterator pattern提供到数据库的完整接口。
我将用一些例子来说明这一点;这里的巧妙之处在于迭代器,因为您可以抽象出更多的东西,并在后面进一步使用一些非常通用的类来提取数据。
要使用上述方法创建用户记录,请执行以下操作:
$user = new DbUser();
$user->create();
$user->set_email('test@example.com');
$user->write();要读取用户记录,请执行以下操作:
$user = new DbUser();
$user->set_email('text@example.com');
if ($user->load_from_fields())
{
}要遍历记录,请执行以下操作:
$user_iterator = DbUser::begin();
if ($user_iterator->begin())
{
do
{
$user = $user_iterator->current();
echo $user->get_email();
} while ($user_iterator->next());
}发布于 2010-03-30 04:09:39
有两种方法可以防止SQL注入攻击:基于黑名单的方法和基于白名单的方法。
黑名单方法意味着您需要检查整个查询字符串,找出不需要的代码并将其删除。这真是太难了。取而代之的是,通过使用参数化SQL来使用白名单方法。这样,您将确保将执行的唯一查询将是您有意使用代码构建的查询,并且任何注入尝试都将失败,因为所有注入查询都将是参数的一部分,因此不会由数据库执行。您正在尝试寻找一种方法来防止在已经建立查询之后的注入,这间接意味着基于黑名单的方法。
尝试在您的代码中使用参数化SQL,这是全球采用的安全编码原则之一。
发布于 2010-03-30 09:10:46
要么参数化,要么尝试构建DB类,以便使用以下内容传递WHERE (以及任何可能使用的值)的所有值:
$db->where(x,y);即。
$db->where('userid','22');在类语料库中使用类似于
function where(var x, var y) // method
{
$this->where .= x . ' = '.mysql_real_escape_string(y);
}当然,这需要清理以支持多个WHERE输入。
https://stackoverflow.com/questions/2540611
复制相似问题