我正在尝试通过使用在上载过程中创建并分配给文件的文件令牌将文件从SQL推送到浏览器。但我的SELECT SQL不适用于其他任何文件id字段,这是唯一一个似乎在这里启动SELECT请求的代码
$item = $_GET['item'];
$sql = 'SELECT * FROM `files` WHERE file_token = '.$item.'';
$result = mysql_query($sql);
if(!$result) {
echo '<div style="padding:8px;background-color:#fae3e3;border:2px solid #b25959;color:#313131;">Error!</div>';
} else {
while($obj = mysql_fetch_array($result)) {
$file_type = $obj['file_type'];
$file_size = $obj['file_size'];
$file_name = $obj['file_name'];
$file_hash = $obj['file_hash'];
$name = 'encrypted/'.$file_hash;
if (file_exists($name)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($name));
ob_clean();
flush();
readfile($name);
exit;
}
}
}
mysql_query("UPDATE `files` SET file_views = file_views+1 WHERE file_token = '.$item.'");
mysql_close();
我的SELECT语句有问题吗?并且令牌在SQL中看起来像这样
示例:3ed3:3ba6:eb24:5816:6d8b:be06:79e1:b20b
答案 0 :(得分:1)
尝试:
$sql = 'SELECT * FROM `files` WHERE file_token = \''.$item.'\'';
答案 1 :(得分:0)
尝试在$ item
周围加上引号 $ sql ='SELECT * FROM files
WHERE file token =“'。$ item。'”';
答案 2 :(得分:0)
正如其他人指出的那样,您的问题与查询数据库时没有正确引用字符串有关。也就是说,SQL Injection总体上存在一个更为根本的问题。让我们来看看你的前两行:
$item = $_GET['item'];
$sql = 'SELECT * FROM `files` WHERE file_token = '.$item.'';
$item
设置为用户提供给您的任何内容,然后直接放入您的查询中。如果用户礼貌并且发送实际文件令牌,那么一切都很好:
// http://example.com/yourapp.php?item=5
SELECT * FROM `files` where file_token = 5;
如果用户发送一些随机数据串怎么办?
// http://example.com/yourapp.php?item=John%20Doe
SELECT * FROM `files` where file_token = John Doe;
上述SQL无效。该字符串需要在其周围加上引号,例如:
SELECT * FROM `files` where file_token = "John Doe";
编辑代码只是简单地添加引号似乎已经足够了解决方案,但事实并非如此。如果我们看一下像这样的解决方案:
$sql = 'SELECT * FROM files WHERE file_token = "'.$item.'"';
我们确实会在用户传入的内容周围添加引号。因此,在John Doe
的示例中,我们将使用John Doe
引用正确的SQL。如果用户决定他们希望提交名为5"; TRUNCATE TABLE files;
“的GET请求,该怎么办?
我们的SQL最终看起来像:
SELECT * FROM files WHERE file_token = "5"; TRUNCATE TABLE files; "";
单个查询现在变为3:
SELECT * FROM files WHERE file_token = "5";
TRUNCATE TABLE files;
"";
你可以尝试通过点燃半冒号或类似物来走得更远;但是没有必要重新发明轮子。查看this great SO answer以了解有关在PHP中阻止SQL注入的详细信息。