确保登录或返回链接url后返回上一页的最佳实践


Best practices for securing return to previous page after login or back link url

我发现了许多登录后重定向到上一页的方法,例如:

  1. $_GET-需要验证
  2. $_SESSION-如果使用多个选项卡,将覆盖该值
  3. $_SERVER['HTTP_REFERER']-由浏览器发送到服务器

在表单上,我们可以使用

<form action="/process/?return=/previous/page/?id=123" method="post" />

或者使用隐藏输入。

<input type="hidden" name="return" value="$_GET or $_SESSION or $_SERVER" />

我可以知道确保回报价值的最佳做法是什么吗?

最常见的做法(也在电子商务网站上的支付结账)是使用URL进行隐藏输入,以重定向到:

<input type="hidden" name="return" value="<?php echo($_SERVER['REQUEST_URI']); ?>" />

它似乎对大多数人来说足够安全。。。

我想到了三种解决方案:

最好的解决方案是创建一个包含所有可能url的白名单,但在大多数情况下这是不可更改的。如果你有可能,你可以自动创建网址(也许从数据库?)。Neverthless:

<?php
  $whitelist = array('url1', 'url2',...);
  $referer = $_POST['referer'];
  if(in_array($referer, $whitelist))
  {
     header('Location: '.$referer);  // redirect to target
  }
  else
  {
     header('Location: /');  // redirect to default page
  }
?>

我想到的第二个解决方案是使用正则表达式检查url(取决于用户的来源)。

第三种解决方案似乎使用密钥来生成令牌,以防止用户篡改表单:

<?php
    $referer = htmlspecialchars($_SERVER['REQUEST_URI'], ENT_QUOTES); // request-url or get value whatever you like
    $secret = 'sfhuwefwejori234'; // key of your choice
    $token = sha1($secret.$referer); 
?>
<form action=....>
  <input type="hidden" name="referer" value="<?php echo $referer; ?>" />
  <input type="hidden" name="refToken" value="<?php echo $token; ?>" />
...

在目标页面上,在重定向用户之前,用传递的值重新创建令牌,并检查它是否正确:

<?php
  $referer = $_POST['referer'];
  $token = $_POST['refToken'];
  $secret = 'sfhuwefwejori234';  // SAME key as above, do never include this into a form, user cannot know this key
  $originalToken = sha1($secret.$referer);
  if($originalToken == $token)
  {
     header('Location: '.$referer); // redirect user
  }
  else
  {
     header('Location: /'); // Redirect to default page
  }
?>

这将保护您免受表单篡改和跨站点脚本的影响。

干杯!

我不明白你在说什么安全。

对于最现代的web应用程序,您不必返回任何位置,因为您只需在整个过程中使用相同的URL。