我在一页(~30)上有多个表单,有些带有文件上传。
每个表单都有自己的提交按钮。
结构是引导选项卡和折叠框设计 - 因此您无需重新加载即可更改选项卡并访问"控制面板"中的每个表单。
我试图为所有形式运行"mysql inject me"(火狐插件),结果:
服务器响应错误 500。
没有改变任何东西,不得不等待5分钟,一切都很好。
我的问题是:如何防止快速自动/用户提交表单(服务器端)? 无论如何这可能吗?这样每个用户每~1秒只能提交一个。
- 向用户提供会话
- 在会话中定义一个名为 last-submit 的变量,并为其指定当前时间作为值。
- 当表单结果出现时:
- 检查上次提交的值是多少。
- 如果超过 x 秒前,则分别将时间保存为上次提交和响应。
- 如果少于 x 秒,请分别拒绝表单并回复。
如果要阻止机器人或脚本,请同时执行以下操作:
- 向表单添加一个输入字段,将其命名为 _robo_trap_ 并通过将样式设置为
display: none
来使其对人眼不可见。 - 当表单进入时,请检查
robo_trap
是否有任何值或其默认值是否已更改。如果是,那就丢弃表格,因为人类看不到,也不需要填写。
例如:
<?php
/* User Session */
session_start();
/* Current Time */
$now = new DateTime();
/* First Time ... */
if ( empty($_SESSION['last-submit']) ) {
$_SESSION['last-submit'] = $now;
}
/* On Form Submit ... */
if ( !empty($_POST) ) {
/* How fast?! */
$gap = now->diff( $_SESSION['last-submit'] );
$gap = $gap->format('%s');
if ( $gap > 1 ) {
// good ...
$_SESSION['last-submit'] = $now;
} else {
// bad ...
}
}
附言只是一个示例代码,给你一些想法,我没有测试它。
为什么不有一个带有用户ID的MySQL表,并有一个名为"last_submit"的行,这是一个datetime
。
每次用户提交内容时更新它。
然后让PHP检查他们最近没有提交一些东西。
您可以暂时禁用其他表单提交操作:
$(document).ready(function(){
$(':input[type="submit"]').click(function(){
var otherButtons = $(':input[type="submit"]').not($(this));
otherButtons.prop('disabled', true);
setTimeout(function(){
otherButtons.prop('disabled', false);
},
1000); //disable for 1 second
});
});
在服务器端,您可以进行重新提交检查,如:PHP 避免浏览器在页面刷新时重新发布 $_POST?