我一直在谷歌搜索但我仍然没有答案所以我决定在这里提出这个问题: 有没有办法在PHP中如何检查我在某些脚本中收到的数据是否来自页面上的特定表单?我问,因为每个人都可以看到我用来保存数据到我的数据库的脚本的名称,所以如果有人能够找到整个URL,他也能够发送一些假数据到脚本,我需要一个条件,即只有当数据来自我页面上的正确表格时才会触发保存过程。
我使用jQuery来调用AJAX函数,所以基本上如果我点击“发送”按钮,会触发$ .POST()方法来调用脚本来保存数据。
谢谢, 托马斯
答案 0 :(得分:2)
提交数据时,您总是可以添加某种安全令牌:
在检查某些请求是否有效时,可以轻松扩展令牌以用于许多不同的用途并涵盖广泛的区域,例如,您可以让非关键表单对公众开放,要求用户从某个页面获取其密钥(强制他们打开该页面),然后在提交数据时使用这些键来识别它们。
当然所有这些对用户来说都是完全透明的,因为你可以通过cookie(或会话cookie)从头版提供密钥,这里无关紧要,因为服务器密钥在使用后应该改变,所以不会有更多或更少的安全性在指定时间内或用户身份发生变化时无效。
在本使用示例中,只有打开首页的用户才能向服务器提交数据。
另一种情况是在同一页面上发布cookie,其中包含用于向服务器提交数据的表单。每个打开页面的用户都会有自己的密钥直接提交数据,但如果有人试图从外部提出请求,则会失败
见OWASP Cross Site Request Forgery
和codinghorror.com Blog CSRF and You
以下是我对另一个问题的回答,这个答案涵盖了向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(); ?>" />
只需生成随机字符串并将其保存到会话存储中
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脚本处理许多不同形式的情况。
<小时/> 请记住,只有防止恶意用户的最终答案才能从您的服务器中取出所有电线......
答案 1 :(得分:1)
这是一个有趣的话题,但您遗漏了一个重点:垃圾邮件机器人/坏用户也可以使用该特定表单页面(!)轰炸您的数据库。
所以,问题不在于如何检查请求是否来自该页面,问题是如何检查他是普通用户还是机器人/垃圾邮件发送者/机器人。
使用验证码进行操作,例如http://www.recaptcha.net
如果我稍微误解了这个问题:如果你想确定请求来自“真实”用户,你必须使用登录系统/用户系统并检查用户id /密码(通过db或每次你想要做一个数据库请求。
答案 2 :(得分:0)
您可以通过AJAX验证是否正在通过以下方式请求页面:
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest'
您还可以查看HTTP_REFERER。
但听起来您正在尝试保护处理易受攻击数据的网页。这需要的不仅仅是上述两件事。我建议谷歌搜索'CSRF Forgery'以获得更多相关信息。
答案 3 :(得分:0)
这些是你应该看看的东西。