0

我使用 PHP、Appache 和 PHPMyAdmin 构建了一个相当基本的本地数据库驱动网站。该站点允许用户上传两种格式的 cad 详细文件。除了文件路径,他们还可以上传文件名、相关服务组以及详细 ID。

基本上,除了从上传页面上传文件时出现一个小问题外,一切都很顺利。一切都很好地提交到数据库,但文件的链接缺少必要的反斜杠。

但是,我可以进入数据库本身并将反斜杠输入到文件路径中。

形式:

<form method="post" action="add.php">
 <table border="0">


 <tr><td>Detail ID: </td><td><input type="number" name="id" /></td></tr>

 <tr><td>Detail Name: </td><td><input type="text" name="name" /></td></tr>

 <tr><td>Service Group: </td><td><input type="text" name="service" /></td></tr>

 <tr><td>PDF: </td><td><input type="file" name="pdf" enctype="multipart/form-data"/></td></tr>

 <tr><td>DWG: </td><td><input type="file" name="dwg"/></td></tr>

 <tr><td></td><td><input type="submit" value="Submit" />
    <input type="reset" value="Reset" /></td></tr>

 </table>
 </form>

PHP:

$con=mysql_connect("localhost","root","");
 /* Select the database */
 mysql_select_db("hrg_test");

 /* Store the values submitted by form in variable */
 $id=$_POST['id'];
 $name=$_POST['name'];
 $service=$_POST['service'];
 $pdf=$_POST['pdf'];
 $dwg=$_POST['dwg'];


 /* Write a query to insert details into database */
 $insert_detail=mysql_query("INSERT INTO hrg_test (id, name, service, pdf, dwg) VALUES ('$id',      '$name',     '$service',     '$pdf',     '$dwg')");

 if($insert_detail)
 { echo "Detail Succesfully Added! <br /><br /><a href='add.html'>Add Another Detail</a>"; }
 else
 { echo "Error".mysql_error(); }

 /* closing the if else statements */

 mysql_close($con);
 ?>

我已经阅读了魔术引号和stripslashes,尽管如果这是问题,我不确定如何将它们联系起来。也许我只是以错误的方式去做。

任何帮助将不胜感激。

4

4 回答 4

1

我想你可以通过在每个输入的 POST 变量分配上使用这些来完成这项工作。

$pdf=mysql_real_escape_string($_POST['pdf']);

然而。这里的问题更深。它现在可能只是一个本地脚本。我们都去过那里。事情变化的速度令人惊讶,而且可能并不总是有时间进行重构(老板喜欢原型并想要昨天完成的应用程序),或者有人复制您的代码(也许是您?)以在更公共的环境中使用。即使此脚本位于“仅限管理员”区域,恶意编码员(或心怀不满的管理员?)也可以访问管理系统,然后能够上传各种讨厌的东西并对您的数据库做一些令人讨厌的事情!没有人相信。

这里简要概述了一些问题,以及如何以低于零的工作成本对其进行改进。

  1. MySQL API。不建议将此扩展用于编写新代码。相反,mysqli 或 PDO_MySQL
  2. 此代码易受数据库注入攻击。您需要转义您的数据。这意味着使数据可以安全地插入数据库(例如转义 ' 字符)。你可以使用mysql_real_escape_string(),但这仍然会留下安全漏洞,并让你有机会忘记逃跑。但是,如果我们选择 PDO 扩展,那么您可以使用参数化查询,您的所有问题都将得到神奇的解决。
  3. 接受用户上传总是有风险的。你越能限制它越好。如果您知道您只想接受某种类型的文件,请确保检查文件类型。如果可能,请将文件移动到无法通过 HTTP 请求访问的位置。如果它必须可通过 HTTP 访问,则尝试将文件重命名为不易猜到的名称。也许是一个 30 个字符左右的随机字符串。这意味着恶意编码人员无法上传名为“bad_things.php”的顽皮 PHP 脚本,只需访问“www.example.com/uploads/bad_things.php”即可让该脚本在您的服务器上运行。您似乎没有在任何地方保存上传的文件,所以我没有提供示例。那里有无数的例子:这里有一些看起来很合理的东西

这是一些示例代码,不仅安全,而且更简单(而且更短,一点都不重要。)


$dbh = new PDO('mysql:host=localhost;dbname=hrg_test', 'root', '');
$stmt = $dbh->prepare("INSERT INTO hrg_test (id, name, service, pdf, dwg) VALUES(?,?,?,?,?)");
$result = $stmt->execute(array($_POST['id'],$_POST['name'],$_POST['service'],$_POST['pdf'],$_POST['dwg']));

if($result){ 
    echo "Detail Succesfully Added! <br /><br /><a href='add.html'>Add Another Detail</a>"; 
}
else { 
    var_dump($stmt->errorInfo());
}
于 2012-12-03T21:55:45.713 回答
0

我将忽略安全问题,因为这是在本地站点上(没有人读过它并明显理解它的含义)。您应该查看 mysqli 或 PDO 等较新的方法,但尝试使用 mysql_real_escape_string() 包装这些值。如果这是问题,那应该避开斜线并允许存储它们。

另一方面,我还开发了一个封闭的公司内部网。尽管我知道怎么做,但在许多情况下,我的老板恳求我放弃不必要的安全措施,因为唯一的访问权限是员工。

如果您还要回答这个问题,指出存在安全问题是可以的……如果不是,那您只是在浪费您和其他人的时间。

于 2012-12-03T21:10:21.097 回答
0

另一件要注意的是双引号的使用。我注意到您的 echo 语句使用了双引号 ("),这会导致引号内的字符串被预处理(变量被扩展等...)。如果您操作任何数据,并将路径放在双引号内的字符串中,反斜杠将将以下字符转换为文字,并使您的反斜杠消失。

例如:

$UploadPath = "New\Drawings";
$NewPath = "C:\UPLOADS\$UploadPath";

在这种情况下,$NewPath 被转换为“C:UPLOADSNewDrawings”,因为每个反斜杠都将其后面的字符变为文字。使用单引号 (') 将防止这种情况,或者使用双反斜杠。

于 2012-12-04T16:58:49.563 回答
0

我的观点 Joe 并不是说​​安全性不重要,只是你没有必要在像 SO 这样的网站上批评代码的安全性。事实上,我很想看到像 SO 这样的网站完全禁止它。如果我问的是安全性,很好,但是如果我发布一个代码片段(我可能只是为了展示我的意思的一个例子而写的)我不应该处理从“这里有 37 个链接关于安全性”到“玩得开心让您的数据库 pwned”或任何有人想留下的时髦评论。

目标应该始终是回答OP的问题。这几乎就像有人在考虑安全原则的那一刻起,他们认为他们需要在互联网上大肆攻击以防止糟糕的编码人员犯错。老实说,我发现这是完全放错了地方的能量,因为绝大多数人的回答是“我知道,这只是一个发帖的例子”。

更不用说,在你的例子中......你说“更简单?” 包括大括号行,你的代码片段是 11 行代码,使用人们应该学习的语法,但可能还不习惯。OP 发布了 14 行代码(其中 5 行将 post 变量设为本地,这是不需要的,并且会将他的代码减少到 9 行。那“更容易”呢?我不想在这里成为魔鬼的拥护者,但是说PDO/mysqli 更简单是一种观点,它们肯定更好,但更简单是一个折腾。

如果安全性是问题的重点,您的回答会很棒……我会诚实地考虑您劫持了什么。

于 2012-12-04T20:49:37.823 回答