【问题标题】:SQL injections from remote file来自远程文件的 SQL 注入
【发布时间】: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。避免表现性元素(例如&lt;b&gt;)并用语义元素替换非语义元素的使用(例如使用&lt;p&gt;而不是&lt;br/&gt;)。您还应该阅读 Markdown 语法帮助,可通过帖子编辑器中的橙色问号访问。

标签: php mysql security code-injection mysql-real-escape-string


【解决方案1】:

欢迎使用 HTTP 协议。

http://www.myserver.com/submit.php 可以随时被任何人调用。调用的表单可以在任何其他网页上。或者用户可能根本不会从表单中调用它,但可能会使用命令行工具来提交数据。这个工具可能声称是一个网络浏览器,而你不会知道。

我从你的 Q 中猜测:

您是否依赖choose-product.php 为submit.php 提供某种安全性?

你不能。

您必须对 submit.php 进行所有安全检查,即使您刚刚在 5 秒前对 choose-product.php 进行了检查。

【讨论】:

  • 啊,刚刚看到你的评论。事情突然变得更加复杂和不清楚。 (顺便说一句,使用 JS 不会使 submit.php 的工作变得不可见。)嗯,很抱歉,您说这是您第一次编写此代码,我认为您需要找一个专业的程序员,尤其是在某些方面作为结帐过程很重要。
  • 不完全是,@James。 choose-product.php:用户选择他们想要购买的产品。单击“立即购买”后,将形成产品 ID 以 submit.php,并在其旁边写入一个密钥。用户不会离开 choose-product.php,因为我正在使用 JavaScript 运行 submit.php 而不离开页面。 “立即购买”按钮变为“结帐”按钮,将用户带到 Google Checkout。付款完成后,之前创建的密码将包含在下载产品的链接中。下载后,密码将被删除。
  • 嗨詹姆斯。这一点都不苛刻。我很感激这个建议。我不是一个完全的新手,我决心学习(虽然我开始认为有经验的程序员可能更容易......!)
  • 嗯,我认为您需要退后一步,看看整个过程,因为我不确定其中的一些原因。如果你不想让专业人士来做这一切,至少让他们先和你一起完成设计,然后再查看完成的代码。我完全是为了学习——我只是鼓励你在不涉及金钱的事情上去做:-)
  • 为什么不简单地根据从 google checkout 收到的返回值创建密钥。或者,如果您真的有/想要在结帐前创建它,请将其存储在会话中而不是隐藏的表单字段中。
【解决方案2】:

这不是注入问题。您的 php 脚本必须在某处具有数据库的位置、用户名和密码。除非您的数据库专门配置为不允许,否则任何拥有该信息的人(例如您的脚本)都可以使用它进行更改。

限制对本地主机的访问很常见,也很容易。我现在正在谷歌上搜索如何做到这一点。

【讨论】:

  • 嗯,您的 PHP 脚本具有 DB 的用户名/密码!=“任何人都可以使用该信息进行更改。”如果您的服务器配置正确,则其他人不应看到该信息。 (尽管您说 MySQL 可以设置为只允许来自本地主机的连接是正确的,这是一个明智的安全预防措施。)
  • 编辑让我的陈述更清楚:php脚本可以更改数据库,因为IT作为访问用户,db,通过。
  • 澄清一下,你认为如果一个 PHP 脚本有一个数据库的主机/用户名/密码,那么世界上任何人都可以找出那个 h/u/p 是什么然后使用他们直接访问MySQL服务器?因为这就是我从你的回答中得到的。
  • 我添加了“任何拥有该信息的人(例如您的脚本)都可以使用它”以明确我是说脚本具有该信息,因此可以使用它。我不是说任何人都可以得到它 - 我是说他将它与脚本一起复制(除非我误解了他的帖子)
  • 我终于明白你的意思了。他复制了我认为没有数据库访问权限的 choose-product.php。关于更改 URL 的内容也暗示这不是问题所在。但我们无法确定,Q 是模糊的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2015-08-12
  • 2012-01-07
相关资源
最近更新 更多