【发布时间】:2012-01-16 19:50:10
【问题描述】:
我有一个文件“submit.php”,它将从“choose-product.php”中的先前表单提交的一系列值写入 MySQL 数据库。我已经使用了mysql_real_escape_string,正如上一个问题中所建议的那样,但我注意到如果我将“choose-product.php”文件上传到单独的服务器并将表单的开头更改为
<form name="form" id="form" action="http://www.myserver.com/submit.php" method="post">
这将也将一系列值写入数据库。显然这是非常糟糕的!现在,我知道会有办法纠正这个问题,但由于这是我第一次编写这样的代码,我有点难过。
这是submit.php的完整代码:
<?php
include("db.php");
function random_string() {
$character_set_array = array();
$character_set_array[] = array('count' => 7, 'characters' => 'abcdefghijklmnopqrstuvwxyz');
$character_set_array[] = array('count' => 1, 'characters' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
$character_set_array[] = array('count' => 3, 'characters' => '0123456789');
$character_set_array[] = array('count' => 1, 'characters' => '!@#$*&:');
$temp_array = array();
foreach ($character_set_array as $character_set) {
for ($i = 0; $i < $character_set['count']; $i++) {
$temp_array[] = $character_set['characters'][rand(0, strlen($character_set['characters']) - 1)];
}
}
shuffle($temp_array);
return implode('', $temp_array);
}
$key = random_string();
if($_SERVER["REQUEST_METHOD"] == "POST") {
$productid = mysql_real_escape_string($_POST['productid']);
mysql_query("INSERT INTO sales VALUES('','$productid','$key',CURRENT_TIMESTAMP,'','active')");
echo "
<form action='XYZ' id='BB_BuyButtonForm' method='post' name='BB_BuyButtonForm' target='_top'>
<input name='item_name_1' type='hidden' value='Test item 1'/>
<input name='item_description_1' type='hidden' value='Testing item sales'/>
<input name='item_quantity_1' type='hidden' value='1'/>
<input name='item_price_1' type='hidden' value='0.5'/>
<input name='item_currency_1' type='hidden' value='GBP'/>
<input name='shopping-cart.items.item-1.digital-content.url' type='hidden' value='http://www.XYZ.com/download.php?key=$key'/>
<input name='_charset_' type='hidden' value='utf-8'/>
<input alt='' src='XYZ' type='image'/>
</form>
";
}
?>
【问题讨论】:
-
mysql 扩展已过时,即将弃用。新代码应该使用 mysqli 或 PDO,两者都有重要的优势,比如支持准备好的语句。准备好的语句参数是防止注入的现代方法,因为它们对注入是无懈可击的。
-
如果我错了,请纠正我,这就是我理解您的问题的方式:当您将代码上传到不同的服务器时,该服务器能够在您的数据库中添加/更新行。您想知道这是什么以及如何阻止其他服务器保存到您的数据库?
-
怎么回事?如果数据来自您服务器上的脚本或托管在不同服务器上的表单,则最终结果仍然相同。如果所有输入都经过正确验证,那么提交表单的托管位置就没有问题。
-
@GordonM - 表单将信息提交到数据库并创建一个密钥,该密钥作为“隐藏”表单输入包含在用户被引导到 Google Checkout 进行付款之前。我正在使用 javascript 将信息发送到 submit.php 而不离开 choose-product.php (因此 submit.php 的工作不可见)。但是如果其他人要复制choose-product.php(减去javascript),他们将被重定向到www.myserver.com/submit.php。右键单击将显示隐藏的密钥,他们将能够完全绕过销售过程。希望这是有道理的!
-
@Martin:从查看您问题的来源来看,您使用的 HTML 不是semantically。避免表现性元素(例如
<b>)并用语义元素替换非语义元素的使用(例如使用<p>而不是<br/>)。您还应该阅读 Markdown 语法帮助,可通过帖子编辑器中的橙色问号访问。
标签: php mysql security code-injection mysql-real-escape-string