Php 基于LIKE算子的MySQL注入

Php 基于LIKE算子的MySQL注入,php,mysql,sql-injection,Php,Mysql,Sql Injection,我在一个php文件中编写了以下代码,用于从数据库中获取数据: $products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\''); 有问题吗?我的意思是像操作员一样可以被注射 已编辑 请提供以这种方式注入的示例当然可以注入,您需要对输入进行消毒。现在,您正在

我在一个php文件中编写了以下代码,用于从数据库中获取数据:

$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\'');
有问题吗?我的意思是像操作员一样可以被注射

已编辑


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

当然可以注入,您需要对输入进行消毒。现在,您正在获取原始post数据并将其插入SQL语句中

您应该通过某种数据清理来运行POST数据,比如mysql\u real\u escape\u string之类


或者至少是准备好的声明。让服务器端代码为您完成这项工作。

任何操作符都可以在不绑定的情况下注入

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

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

请继续阅读。

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

通过将变量插入字符串中,使其不再像“命令”那样工作,而是像“值”一样工作,构造一个稍后准备和执行的字符串

您可以这样做:

$query = "SELECT * from products WHERE shop_id = :shopId;"; // An example, you can finish the rest on your own.
现在,您可以准备语句了(我建议为此使用PDO)

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

$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传递到函数中,而不是会话本身,然后检查会话是否确实存在


我建议用谷歌搜索如何使用PDO,或者看看我的一个例子:

这真的很糟糕。将变量拉入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'].'"');
如果您回显一条消息,该消息表示“$\u POST['email']不存在用户名”,则可以用其他内容替换

$_POST['email']=";

$fp = fopen('index.php', 'w');
fwrite($fp, \"header('Location: http://badwebsite.com;');\"; 
fclose($fp);";
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);
 }

是的,它可以被注入。在SQL中,任何东西都可以被注入。你是完全开放的。仅仅因为它在
类似的部分就意味着什么都没有。这样做并没有什么神奇之处,它是无懈可击的。SQL注入攻击中被利用的不是运算符,而是参数。使用预先准备好的语句,您将删除此攻击选项。第三个最常见的问题是如何查询您的数据库:@rev:
$\u POST['search']='%\';投球台学生;——”。与任何sql注入发生的方式相同。请记住:db不可能看到您从$\u POST插入了一些数据。它只看到一条sql语句。如果该语句格式正确,它将执行。RTLM:
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);
 }