用于验证表单发布数据的CakePHP安全组件令牌是不同的 - >黑洞

时间:2013-07-30 17:31:38

标签: forms security cakephp

我在使用安全组件验证已发布的表单时遇到问题,并且它一直在阻止操作。查看代码,我发现散列标记不匹配。

在发布的表单中,只有一个字段被验证(在Security :: _ validatePost中)被锁定。但是我在找到Form->创建令牌的位置以及如何生成时遇到了问题。

令牌不匹配的典型原因是什么?我应该在哪里检查蛋糕如何生成令牌[' _Token'] ['字段']和? (使用蛋糕2.3.7)。该表单也使用了ajax验证。

编辑:当我从Security :: generateToken中转出$ token值时,它看起来像

  

阵列(       [key] => ddc88faacf41985f41359ff99d9c6f87549611c7       [allowedControllers] =>排列           (           )

[allowedActions] => Array
    (
    )

[unlockedFields] => Array
    (
    )

[csrfTokens] => Array
    (
        [f8c40609a0a86db23bfa5ea2d258723d3caff55a] => 1375207459
        [084c3363363591c3024c59452899a2f4f60ecf99] => 1375207655
        [0344c686c549927c1e27729ae95d879a4034bdab] => 1375207678
        [dfb940ec034e82b10f7b3cc5677734da6896dfbc] => 1375207762
        [ddc88faacf41985f41359ff99d9c6f87549611c7] => 1375207791
    )

但是对于创建的表单,发布表单时Security :: _ validatePost中的标记是

  

标记= 6521bb362f8323e8f871814fc5d37a79c93e294e   检查= e8c40d174a23e8797d906d6e381a9a0acc1425ed

获取令牌
$check = $controller->request->data;
$token = urldecode($check['_Token']['fields']);

并且检查后来被重新定义为:

$check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'), 'sha1');

然后将$ token和$ check进行比较,并将其与导致黑洞的错误进行比较。

2 个答案:

答案 0 :(得分:4)

我发现一个字段没有被添加到POSTED表单字段的列表中,因为它是一个未经检查的CHECKBOX(参见下面的编辑)。我想我会概述一个通用的调试程序来帮助人们处理安全表格验证问题。

为了查看我在代码中挖掘的机制,看看如何创建FormHelper哈希以及SecurityComponent验证如何检查哈希。以下是如何准确了解幕后发生的事情。

检查FormHelper的输入。打开CORE / Cake / View / Helper / FormHelper.php。在secure()函数中,在$ files = Security :: hash行周围添加一些pr行,看看如何构建标记:

pr($fields);//hashed into computed token on next line
$fields = Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt'), 'sha1');
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($fields); //computed token passed via hidden token field in form

检查表单的处理方式 现在检查提交的表单如何处理并与传递的令牌进行比较: 打开CORE / Cake / Controller / Component / SecurityComponent.php。在_validatePost()例程的末尾插入一些pr行:

pr($fieldList); //hashed into computed token
pr($unlocked); //hashed into computed token
pr(Configure::read('Security.salt')); //hashed into computed token
pr($token); //passed token from FormHelper
pr($check); //computed token

希望这可以帮助那些遇到锁定/解锁或丢失字段问题的人快速弄清楚蛋糕内部的情况。

编辑: 导致问题的领域是CHECKBOX。如果用户未选择该字段,则POST操作不会提交该字段。缺少的字段导致SecurityComponent失败。要在复选框中避免这种情况,请将其添加到表单中:

$this->Form->unlockField('checkbox.field.name');

答案 1 :(得分:1)

您是否在视图中使用Javascript创建或删除了字段?你去吧See also the book for the security component

如果要使用这些字段,则必须将这些字段列入白名单。