文件路径返回斜杠

时间:2012-12-03 21:01:01

标签: php phpmyadmin

我使用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);
 ?>

我已经阅读了有关魔术引号和条带的信息,但我不知道如果问题如何将它们绑在一起。也许我只是以错误的方式去做。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

我想你可以通过在每个输入的POST变量赋值中使用它们来实现这一点。

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

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

这里有一点简要介绍一些问题,以及如何以低于零成本的方式改进它。

  1. MySQL API。 This extension is not recommended for writing new code. Instead, either the mysqli or PDO_MySQL
  2. 此代码容易受到数据库注入攻击。您需要转义数据。这意味着可以安全地插入数据库(例如,转义'字符)。你可以使用mysql_real_escape_string(),但这仍然会留下安全漏洞,让你有机会忘记逃跑。但是如果我们选择PDO扩展,那么你可以使用参数化查询,你的所有问题都将被神奇地解决。
  3. 接受用户上传总是有风险的。你越能限制它就越好。如果您知道您只想接受某种类型的文件,请确保检查文件类型。如果可能,将文件移动到无法通过HTTP请求访问的位置。如果必须通过HTTP访问它,那么尝试将文件重命名为不容易猜到的内容。也许一个30个字符左右的随机字符串。这意味着恶意程序员无法上传名为“bad_things.php”的顽皮PHP脚本,只需访问“www.example.com/uploads/bad_things.php”即可在您的服务器上运行该脚本。你似乎没有在任何地方保存上传的文件,所以我没有包括一个例子。有无数的例子:here's something that looks pretty reasonable
  4. 以下是一些示例代码,它不仅安全,而且更简单(也更简短,而不是一个小问题。)


    $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());
    }
    

答案 1 :(得分:0)

我会忽略安全问题,因为这是在本地站点上(没有人读过它并且明显地摄取它意味着什么)。您应该查看更新的方法,如mysqli或PDO,但尝试使用mysql_real_escape_string()包装值。如果这是问题,那应该逃避斜线并允许它们存储。

另一方面,我也开发了一个封闭的企业内部网。即使我知道如何,在很多情况下,我的老板要求我放弃不必要的安全措施,因为唯一的访问权限是员工。

如果你也要回答这个问题,指出存在安全问题是好的......如果没有,你只是在浪费你的和别人的时间。

答案 2 :(得分:0)

另一件值得关注的是使用双引号。我注意到你的echo语句使用双引号(“)引起引号内的字符串被预处理(变量被扩展等等)。如果你操纵任何数据,并将路径放在双引号内的字符串中,反斜杠将将以下字符转换为文字,并使反斜杠消失。

例如:

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

在这种情况下,$ NewPath被转换为'C:UPLOADSNewDrawings',因为每个反斜杠使得后面的字符成为文字。使用单引号(')可以防止这种情况或双反斜杠。

答案 3 :(得分:0)

我的观点Joe并不认为安全性并不重要,只是因为您没有必要批评像SO这样的网站上的代码中的安全性。事实上,我希望看到像SO这样的网站完全禁止它。如果我问安全性,那很好,但是如果我发布一个代码片段(我可能只是为了展示我的意思而写的)我不应该处理一系列评论,范围从“这里有37个链接关于安全“to”获得有趣的数据库pwned“或任何有人想留下的快速评论。

目标应始终是回答OP的问题。这几乎就像有人围绕安全原则,他们认为他们需要通过互联网来挽救糟糕的程序员犯错误。老实说,我发现这是完全错位的能量,因为VAST大多数人回答“我知道,这只是一个发布目的的例子”。

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

如果安全性成为问题的焦点,你的答案会很好......我会诚实地考虑你劫持了什么。