使用$ _GET& $ _ POST

时间:2009-08-09 22:12:50

标签: php sql-injection

也许我从一开始就做错了,如果是的话,我也会这样做......

我有一个菜单项,作为URL的一部分传递了一个事件ID#。在我的特定情况下,它将用户带到该事件的信息页面。然后有一个按钮,让他们注册参加活动。点击它们并注册参加活动并返回到相同的信息页面,现在它们已经注册并让他们看到一些额外的东西。

当他们第一次点击页面时,我使用$ _GET来计算事件ID#,如果他们点击注册按钮作为隐藏输入字段,则会将其传递回页面。但这次我需要使用$ _POST来计算事件ID#。所以我的查询中的代码有一个布尔部分,看起来像

SELECT stuff FROM ... WHERE eventID = ($_GET["ID"] ? $_GET["ID"] : $_POST["ID"])

它有效,但感觉它可以做得更好......

5 个答案:

答案 0 :(得分:8)

  1. 清理数据库输入。 mysql_real_escape_string()是实现此目标的快捷方式(或者,如果ID始终为数字,则可以使用intval())。不要像Bobby Tables那样的学校。
  2. 如果您不确定使用了哪种请求方法,请使用$_REQUEST超全局,其中包含GET和POST变量(例如:$_REQUEST['ID'])。我通常不使用$_REQUEST,因为我想清楚我的数据来自哪里,但这是一个完美的使用方式。
  3. 正如Nick Presta所指出的,$_REQUEST还包含cookie变量,事实上,名称冲突的默认*优先顺序是$_COOKIE$_POST,然后$_GET。鉴于此,在您将数据插入查询之前,您可以执行您现在正在执行的操作,也可以使用$_SERVER['REQUEST_METHOD']代替:

    // You can use mysql_real_escape_string() instead if you want
    $id = ($_SERVER['REQUEST_METHOD'] == 'POST') ? intval($_POST['id']) : intval($_GET['id']);
    

    此外,正如outis所指出的那样,请记住,您可以选择使用prepared statements而不是原始SQL查询。

    * - 正如Stewart在评论中提到的那样,通过variables_order配置指令排序为configurable

答案 1 :(得分:3)

肯定可以做得更好。首先,在查询数据库之前清理用户输入。你已经打开了自己的SQL注入。

答案 2 :(得分:2)

为了简单起见,请结合之前的建议:

"SELECT stuff FROM ... WHERE eventID = '" . mysql_real_escape_string($_REQUEST['id']) . "';"

对于记录,不要对数组键使用双引号,除非您要包含任何需要解析的变量或转义,否则处理时间会更长。例如:

$_POST['id'] and not $_POST["id"] unless you're doing something like $_POST["post_$id"]

希望有所帮助。

答案 3 :(得分:1)

除了htw的回答,如果向用户显示的事件ID基于权限,请确保重新验证他们是否允许该特定ID。
仅仅因为它处于隐藏的领域,并不意味着它们无法改变它。

答案 4 :(得分:0)

您应该将提供的ID的选择与其放入数据库的位置分开。换句话说,一旦页面知道它是通过GET还是POST调用它就会知道正确的超全局来检索ID。实际上,可能会有一些页面始终使用POST调用,而其他页面始终使用GET调用。

如果从中获取ID无关紧要,请使用$ _REQUEST。