PHP更安全的重定向方式

时间:2015-05-26 14:46:53

标签: php mysql mysqli

我有一个php页面,它执行插入操作,然后重定向到"成功"显示订单详细信息的页面。我通过使用变量重定向,但我认为这不是那么安全:

header("location:success.php?id=$orderid");

这会生成如下网址:success.php?id=22

然后我使用该URL获取订单ID号并根据其进行查询以显示订单详情:

$getName = explode('?id=', $_SERVER['REQUEST_URI']); 
$id = $getName[1];

$query = <<<SQL
SELECT * FROM `order` WHERE `orderid` = ?;
SQL;

$request = $mysqli->prepare($query);
$request->bind_param("i", $id);
$request->execute();

显而易见的问题是,任何人都可以简单地更改URL ID号以获取不同订单号的详细信息。我并不十分担心,因为这严格来说是一个内部网站,但我仍然想解决这个问题。是否有更好,更安全的方法来做到这一点?

4 个答案:

答案 0 :(得分:4)

这是一个更简单的解决方案:在会话中存储orderid,如$_SESSION['orderid'] = $orderid

在重定向上你会得到它的价值如下:

$getName = explode('?id=', $_SERVER['REQUEST_URI']); 
$id = $_SESSION['orderid'];

$query = <<<SQL
SELECT * FROM `order` WHERE `orderid` = ?;
SQL;

$request = $mysqli->prepare($query);
$request->bind_param("i", $id);
$request->execute();

答案 1 :(得分:1)

一般而言,允许客户查看过去订单而不允许其他人查看此订单的问题有两个步骤。

  1. 设置授权策略:确定允许哪些用户查看哪些订单号。这应该包括能够在以后的会话中返回并查看订单的状态。
  2. 使用身份验证方法支持:存储并检索足够的信息以识别用户。
  3. 要考虑的授权政策包括以下内容:

    1. 允许刚下订单的用户在同一会话中查看。这是您在问题中描述的政策。
    2. 下订单会创建唯一ID。任何拥有此ID的人都可以查看。
    3. 创建用户帐户,提供电子邮件地址并验证在该地址接收邮件的能力的人员可以列出与该帐单电子邮件关联的订单并查看这些订单。
    4. 允许提供正确的订单ID和发货邮政编码(或订单处理所需的其他PII)的人查看该订单,但不能列出任何订单,并且这对于每个IP地址以某种方式受到速率限制。 (大NAT背后的用户还有其他三种选择。)
    5. 要实施策略1(同一会话),您可以将订单ID存储在会话中,无论是在PHP的$_SESSION中还是在单独的会话属性表中,只要订单被标记为支付。然后,当用户尝试查看订单时,如果订单ID与此会话的最新订单匹配,则可以允许该订单。

      要实施策略2(唯一ID),您可以生成并存储适当长的随机标识符,例如version 4 UUID,并将其与订单一起存储。警告用户:&#34;小心:看到此订单ID的任何人都可以查看和更改您的订单。&#34;

      要在一个笔划中实施策略1和2,您可以存储每个订单的会话ID,在成功页面上显示会话ID,然后让用户搜索与特定会话关联的订单。

      要实施策略3(控制计费电子邮件),您可以添加用户表,包括用户ID,密码哈希,电子邮件地址和(可空)电子邮件确认日期。这还可以让您有机会添加用户创建的产品列表,这样您就可以在产品重新库存时添加警报等功能。

      要实施策略4(订单ID和发货信息),您可以创建一个表,记录有关每个请求的IP地址,日期和更多信息,应用启发式方法来确定脚本强力攻击是否正在进行中,以及然后将用户提供的运输邮政编码与订单中的邮政编码进行比较。

      在您继续开发商店应用程序时,请牢记这些政策和机制,因为它们可能会提高其可用性。

答案 2 :(得分:-1)

在您的系统上我假设您的订单与您的用户相关。

例如顺序:1234与用户有关:5

检查你的success.php上的这种关系

如果您的方案没有用户订单关系,我强烈推荐它。但是如果订单由匿名用户做,哈希order_id

基本上像

select * from order where order_id = 1234 and userid =5 

如果此查询返回一行,则该用户确实拥有此订单。其他错误。

if($returnedRow == 1){
 //Do something here
}else{
 //access denied. You are not owner of this order.
}

正如我所说,计数返回行,这是简单的方法。此外,如果您像dfljfk45498ds545那样哈希您的order_id,那么它可能不太可预测。您可以使用 uniqid() 来实现此目的。

答案 3 :(得分:-3)

使用Cookie或会话发送"$orderid" *会话更好