我们在用户执行两次特定操作时遇到一些问题,我们有一种机制可以确保用户不能这样做,但不知怎的,它仍然会发生。以下是我们当前机制的工作原理:
然而,通过所有这些措施,仍然有用户能够执行两次操作,是否有更安全的方法?
以下是数据库端的部分代码:
$db->beginTransaction();
// Get the user's datas
$user = $db->queryRow("SELECT flag FROM users WHERE userid = {$auth->getProperty('auth_user_id)}");
if ($user['flag'] != 0) {
$db->rollback();
// Return with error
return false;
}
// Proceed with performing the action
// --- Action Here ---
// Double checking process, the user data is retrieved again
$user = $db->queryRow("SELECT flag FROM users WHERE userid = {$auth->getProperty('auth_user_id)}");
if ($user['flag'] != 0) {
$db->rollback();
// Return with error
return false;
}
// --- The final inserting query ---
// Update the flag
$db->query("UPDATE users SET flag = 1 WHERE userid = {$auth->getProperty('auth_user_id)}");
$db->commit();
return true;
答案 0 :(得分:1)
很高兴看到你已采取一切措施打败坏人。谈到坏人:
客户端:只需禁用javascript即可轻松绕过此功能。很高兴反正但又不能反对坏人。
服务器端:这很重要,但请确保每次提交都生成不同的哈希/密钥。这是 good tutorial at nettutes on how to submit forms in a secure fashion.
数据库端:不确定,但我怀疑,可能存在SQL注入问题。查看有关 SQL Injection 和 how to possibly fix that.
<强>最后:强>
我建议您查看:
<强> OWASP PHP Project 强>
OWASP PHP项目的目标(OWASP PHP项目路线图)旨在使开发人员,系统管理员和应用程序架构师能够构建和部署使用PHP编程语言构建的安全应用程序。
答案 1 :(得分:0)
JS方法和Hash方法可能会被一些臭名昭着的人欺骗,但第三种方法似乎非常好,以保护冗余。必须有一些编程漏洞才能通过这个。
为什么不检查插入值的页面上的标志字段,而不是用户执行操作的位置(如果您现在正在执行此操作)
答案 2 :(得分:0)
伪代码如下:
<?
$act_id; // contains id of action to be executed
$h = uniqid('');
// this locks action (if it is unlocked) and marks it as being performed by me.
UPDATE actions SET executor = $h WHERE act_id = $act_id AND executor = '';
SELECT * FROM actions WHERE executor = $h;
//
// If above query resulted in some action execute it here
//
// if you want to allow for executing this exact action in the future mark it as not executed
UPDATE actions SET executor = '' WHERE act_id = $act_id;
重要的事情: