我在我的一个 php 文件中使用以下代码从数据库中获取数据:
$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\'');
有问题吗?我的意思是可以注入 LIKE 运算符?
已编辑
请提供以这种方式注入的示例
我在我的一个 php 文件中使用以下代码从数据库中获取数据:
$products = $this->db->get_rows('SELECT * from products WHERE shop_id='.$_SESSION['shop_id'].'AND tags,title,text LIKE \'%'.$_POST['search'].'%\'');
有问题吗?我的意思是可以注入 LIKE 运算符?
已编辑
请提供以这种方式注入的示例
任何算子都可以在没有绑定的情况下注入。
$_POST['search'] = "1%'; DROP TABLE myTable LIKE '%";
将使
.... AND tags,title,text LIKE '%1%'; DROP TABLE myTable LIKE '%%'
阅读如何绑定参数。
当然这可以注入,你需要清理你的输入。现在,您正在获取原始发布数据并将其插入到您的 SQL 语句中。
你应该通过某种数据清理来运行你的 POST 数据,比如 mysql_real_escape_string 之类的
或者至少准备好的陈述。让服务器端代码为您完成工作。
永远不要使用这样的数据库查询,不要用变量构造字符串并将其用于数据库活动。
通过将变量插入到字符串中,构造一个稍后将准备和执行的字符串,使它们不像“命令”而是像“值”。
你可以这样做:
$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 传递给函数,而不是会话本身,并检查会话是否实际存在。
我建议使用谷歌搜索如何使用 PDO,或查看我的一个示例:How to write update query using some {$variable} with example
这真的很糟糕。将 var 拉入 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);
}