SQL Select不基于查询检索数据


SQL Select not retrieving data based on query

我正试图通过使用在上传过程中创建并分配给文件的文件令牌,将文件从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

尝试:

$sql = 'SELECT * FROM `files` WHERE file_token = '''.$item.'''';

尝试在$item 上加引号

$sql='SELECT*FROM files WHERE file_token="'.$item.'"';

正如其他人所指出的,您的问题与查询数据库时没有正确引用字符串有关。也就是说,一般来说,SQL注入还有一个更根本的问题在起作用。让我们来看看你的前两行:
$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; 
"";

你可以尝试通过点画分号或类似的方式走得更远;但没有必要重新发明轮子。查看这个伟大的SO答案,了解在PHP中防止SQL注入的细节。