我被迫生成动态SQL。我意识到这样做非常复杂,下面的例子很愚蠢,显然不需要动态SQL,只是用来说明这个问题。
转义用户提供的数据是不够的,下面脚本中的第3个查询可能是SQL注入。
我发现设计应用程序通常最容易,因此所有用户输入都是整数,只需使用(int)$_POST['user_input']
对其输入进行类型转换。
我现在需要user_input需要是text。我该怎么做才能防止SQL注入?一个选项是PHP的ctype_alpha()
,但是,我不希望“用户,输入”结果为FALSE,但应保持原样或转换为“userinput”(或者scenerio对我来说没问题)。我在想$user_input= preg_replace('/[^a-z0-9,]/i', '', $_POST['user_input']);
之类的东西。这是100%安全吗?
修改
请注意,我没有执行以下查询,而是将其插入到数据库中,因此,准备好的语句不适用。您可能认为永远不应该使用动态SQL生成,但告诉我使用预准备语句是不对的。
<?php
$id=123;
$query='SELECT * FROM someTable WHERE someColumn="'.$_POST['user_input'].'"';
$sql='INSERT INTO meta_table (id,sql) VALUES (?,?)';
$stmt=db::db()->prepare($sql);
$stmt->execute(array($id,$query));
$sql='SELECT sql FROM meta_table WHERE id=123';
$stmt = db::db()->exec($sql);
$query=$stmt->fetchColumn();
$stmt = db::db()->exec($query); //Prone to SQL Injection
$rs=$stmt->fetchColumn();
?>
答案 0 :(得分:4)
以下是答案:
你的想法&#34;动态&#34; SQL本质上是错误的。没有人这样做。
我不知道你的特定任务,但你的解决方案显然是错误。并且肯定有一种理智的方式来做到这一点。只需遵循以下简单规则:
让您的所有SQL完全安全