0

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

4

3 回答 3

1

尝试:

$sql = 'SELECT * FROM `files` WHERE file_token = \''.$item.'\'';
于 2013-07-08T13:02:46.367 回答
0

正如其他人指出的那样,您的问题与查询数据库时没有正确引用字符串有关。也就是说,一般来说,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的正确 SQL 。John Doe如果用户决定他们希望提交一个带有术语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 注入的详细信息。

于 2013-07-08T13:14:18.047 回答
0

尝试在 $item 周围加上引号

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

于 2013-07-08T13:02:21.017 回答