使用令牌检查请求是否有效
您总是可以在提交数据时添加某种安全令牌:
在检查某些请求是否有效时,令牌可以很容易地扩展到许多不同的用途,并且覆盖范围很广,例如,您可以让您的非关键表单向公众开放,要求用户从某个页面获取他们的密钥(强制他们打开该页面),然后在提交数据时使用这些键来识别他们。
当然,所有这些都可以对用户完全透明,因为您可以通过 cookie(或会话 cookie,在此处无关紧要,没有更多或更少的安全性,因为服务器密钥在使用后应该更改)并在指定时间内或用户身份发生变化时失效)。
在此使用示例中,只有打开首页的用户才能向服务器提交数据。
另一种情况是 cookie 在包含用于向服务器提交数据的表单的同一页面上分发。每个打开页面的用户都会有他们的密钥来立即提交数据,但是如果有人试图从外部发出请求,它将失败。
见OWASP Cross Site Request Forgery
和codinghorror.com Blog CSRF and You
仅使用 AJAX?
这是我对另一个问题的回答,这个回答涵盖了向 ajax 请求插入附加数据的不同方法:Liftweb: create a form that can be submitted both traditionally and with AJAX(仔细查看
$.ajax({
...
data: /* here */
...
目前我以这种方式使用令牌:
用于提交的表单
这个隐藏的输入可以添加到表单中,这不是必需的,因为您可以使用前面描述的方法at another answer。
<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />
函数 generateFormId()
只需生成随机字符串并将其保存到会话存储中
function generateFormId() {
// Insert some random string: base64_encode is not really needed here
$_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
// If you want longer random string mixed with some other method just add them:
//$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
return $_SESSION['FORM_ID'];
}
处理提交的表单数据
if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
// You can use these if you want to redirect user back to form, preserving values:
//$_SESSION['RELOAD_POST'] = $_POST;
//$_SESSION['RELOAD_ID'] = uniqid('re');
echo 'Form expired, cannot submit values.';
//echo '<a href="form.php?reload='.$_SESSION['RELOAD_ID'].'">Go back and try again</a>';
exit(1); // <== Stop processing in case of error.
}
如果需要查看哪个表单提交数据
然后您可以在生成 id 时添加前缀,并在处理表单数据时检查该前缀。
当一个 php 脚本处理许多不同的表单时,就会出现这种情况。
请记住,防止恶意用户的唯一最终解决方案是是从您的服务器上拔下所有电线...