LIKE运算符的MySQL注入

时间:2013-03-22 21:10:48

标签: php mysql sql-injection

我在我的一个php文件中使用以下代码来从DB中获取数据:

$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\'');

有问题吗?我的意思是LIKE运算符可以注入吗?

被修改

请提供以这种方式注入的示例

4 个答案:

答案 0 :(得分:8)

任何操作员都可以无约束地注入。

$_POST['search'] = "1%'; DROP TABLE myTable LIKE '%";

会制作

.... AND tags,title,text LIKE '%1%'; DROP TABLE myTable LIKE '%%'

继续阅读how to bind parameters

答案 1 :(得分:2)

当然可以注入,你需要清理你的输入。现在,您正在获取原始发布数据并将其插入到SQL语句中。

你应该通过某种数据清理来运行你的POST数据,比如mysql_real_escape_string之类的东西

或至少准备好的陈述。让服务器端代码为您完成工作。

答案 2 :(得分:1)

永远不要使用这样的数据库查询,不要使用变量构造字符串并将其用于数据库活动。

构造一个稍后准备和执行的字符串,方法是将变量插入到字符串中,使它们不像“命令”,而是“值”。

你可以这样做:

$query = "SELECT * from products WHERE shop_id = :shopId;"; // An example, you can finish the rest on your own.

现在,您可以准备声明(我建议使用PDO)。

 $statement = $db->prepare($query); // Prepare the query.

现在您可以在准备好的查询中执行变量:

$statement->execute(array(
    ':shopId' => $_SESSION['shop_id']
));

如果您正在插入或更新,那么您可能希望这样做:

$success = $statement->execute(array(
    ':shopId' => $_SESSION['shop_id']
));

在$ success中存储布尔值,或者如果您正在选择,则可以从结果中获取值:

$statement->execute(array(
    ':shopId' => $_SESSION['shop_id']
));
$result = $statement->fetch(PDO::FETCH_ASSOC);
if($result )
{
    // You can access $result['userId'] or other columns;
}

请注意,您实际应该将其设为函数,并将$ shopId传递给函数,而不是会话本身,并检查会话是否实际存在。

我建议使用Google搜索如何使用PDO,或者查看我的一个示例:How to write update query using some {$variable} with example

答案 3 :(得分:1)

这真的很糟糕。将vars拉入SQL语句而不清除或检查它们是获取pwnd的好方法。人们可以将几种东西注入代码中。要注意的另一种注射方法,1 = 1总是返回true。

$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\'');

//This example expects no result from the table initially so we would blind attack the DB to pull the admin record.
$_POST['search'] = "-1\'; union all select * from users limit 1;";

有人打电话拉起数据库中的最高帐户(比如管理员)。

$user_id = $this->db->get_rows('SELECT * from users WHERE email="'.$_POST['email'].'" and password="'.$_POST['password'].'"');

//This always returns true so now I'm the admin again
$_POST['password'] = "x\' or 1=1 limit 1";

您还要小心在屏幕上打印的内容。

$user_id = $this->db->get_rows('SELECT * from users WHERE email="'.$_POST['email'].'" and password="'.$_POST['password'].'"');

您回复的消息显示“$ _POST ['email']不存在用户名”可以替换为其他内容。

$_POST['email']=";

$fp = fopen('index.php', 'w');
fwrite($fp, \"header('Location: http://badwebsite.com;');\"; 
fclose($fp);";

index.php现在可以将人们带到一个完全存在受感染页面的网站或网站上的受感染页面。

如果您正在检查ID,请执行以下操作:

if(preg_match('!^[0-9]$!',$_POST['id'])){
    $id = $_POST['id'];
} else {
  //flush
}

或计算可能记录的数量...如果您只是期望一个,并且您获得了数据库中的所有记录,那么这是一次注射尝试。

 if(is_numeric($_POST['id'])){
    $id = $_POST['id'];
    $count = mysql_result(mysql_query("select count(*) from users where id='$id''),0);
 }