我发现了许多登录后重定向到上一页的方法,例如:
$_GET
-需要验证$_SESSION
-如果使用多个选项卡,将覆盖该值$_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。