如何Symfony2的CRSF保护工作?(How does Symfony2 CRSF protec

2019-09-28 07:42发布

我试图通过测试Symfony2的,非常感谢他们所做的CRSF保护系统。
我security.yml模板(我修改了默认的。)

security:

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        login:
            pattern:  ^/demo/secured/login$
            security: false
        secured_area:
            pattern:    ^/demo/secured/
            form_login:
                check_path: _security_check
                login_path: _demo_login
                csrf_provider: form.csrf_provider
            logout:
                path:   _demo_logout
                target: _demo
            #anonymous: ~
            #http_basic:
            #    realm: "Secured Demo Area"

    access_control:
        #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

在我的表格:

<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">

产生这样的:

<input type="hidden" name="_csrf_token" value="cKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw">

我不知道symfony中如何处理与验证令牌,但在提交我的登录之前,我改变了使用人工萤火虫看起来像这样的标记的值:

<input type="hidden" name="_csrf_token" value="MODIFIEDcKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw">

当我提出我登录,我得到登录。这意味着令牌没有影响。 在那里我收到错了吗?


猎鹬

  1. Symfony的版本是2.5.2
  2. 该系统签署了我,当我手动设置会话变量“记录”为真。 这种情况从数据库读取和比较后的密码。
  3. HTML表单!

     <form id="Loginform" onsubmit="OrganicLogin();return false;"> <input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}"> <div id="Loginresponse" style="display:none;"></div> <div class="form-group" style="overflow:hidden;"> <label style="margin-top:10px;" for="inputUsername" class="col-lg-2 control-label">Username</label> <div class="col-lg-10"> <input type="text" class="form-control" id="inputUsername" placeholder="Username" style="width:215px;float:right;"> </div> </div> <div class="form-group" style="overflow:hidden;" > <label style="margin-top:10px;" for="inputPassword" class="col-lg-2 control-label">Password</label> <div class="col-lg-10"> <input type="password" class="form-control" id="inputPassword" placeholder="Password" style="width:215px;float:right;"> </div> </div> <div class="form-group" style="overflow:hidden;text-align:center;" > <button type="submit" class="btn btn-primary btn-block" id="submitButton">Access</button> </div></form> 
  4. 是的! 我做了

  5. 其实什么我争论的全部时间,我做了登录过程本机方式,形式,读取数据的JS,发送POST请求到控制器,控制器检查输入和设置会话。

  6. 没有,全部由手工完成

  7. 其实这是我第一次使用security.yml,我只是去掉了一些部分我判断为不有用此线程

  8. 不..

Answer 1:

我有点猜测将更改后的令牌没有得到公布。 坚持一个模具中:

namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider;

class DefaultCsrfProvider implements CsrfProviderInterface
{
    public function isCsrfTokenValid($intention, $token)
    {
        die('csrf token ' . $intention . ' ' . $token);
        return $token === $this->generateCsrfToken($intention);
    }

如果达到了模具那么你知道你的配置是可以的,当然你可以看到实际的发布令牌。

不用说,你也应该clearcache。

================================================== =====

更新1 - 很多评论后,我们已经确定,模具()不会被调用。 进展。

不幸的是,我们仍然需要验证的海报究竟如何配置自己的系统。

下一步 - 登录不通过萤火调整CSRF令牌,并验证是否达到模具声明。

报告这样或那样的。

不用说(但我可以说是反正),请确保您尝试重新登录之前注销。

================================================== ======

更新2 - 模具语句不即使正常登录到达。

所以现在来我最喜欢的部分。 猎鹬。 基本上,我读提问时作一些假设。 需要确定通过询问一些基本问题,这些假设是不正确的。

  1. 您正在使用哪个Symfony的2版本。 我至少S2.1假设。

  2. 你如何知道系统已经签署了你? 您是否使用了调试工具栏,它显示您作为被验证? 当您尝试使用不正确的密码登录,会发生什么?

  3. 使用浏览器的查看源代码的功能和产生形式复制到你的问题。 特别是我想看到的action属性,但我也希望看到的输入元素。

  4. 你实际上添加模具语句供应商/ symfony中/ symfony中/ src目录/ Symfony的/分量/表格/ CSRF / CsrfProvider / DefaultCsrfProvider.php? 你保存文件编辑之后?

  5. 你其实都是使用标准form_login过程吧? 您没有任何代码,例如,检查用户的密码?

  6. 您是否使用任何其他包像也许FOSUserBundle?

  7. 在你的问题中security.yml文件真的是你的实际文件? 你没有“清理”复制后?

  8. 你检查你的应用程序到GitHub上? 如果是这样,那么你可以提供一个链接? 综观整个应用程序可能会清除这个了最快的方法。

这应该现在就足够了。 与你的答案更新您的问题。

================================================== =======================

更新3 - 情节复杂

正如我在上面的问题中键入我们发现基本的登录系统本身的配置不正确。 调试工具栏显示用户没有通过认证。 更进步! 由于经常发生,症状掩盖了实际问题。

该安全系统可以说是在的Symfony 2中最复杂的组件,典型的开发人员需要进行交互。 这很容易配置,当它感到困惑和难以解决的。 一个微小的错字可以融化下来。 这也是非常重要的是,开发商对安全是如何实现工作的认识。 当然,除非你是一个真正的大公司如目标或家得宝。

我的建议是创建一个使用作曲家新鲜的Symfony 2项目。 然后再通过http://symfony.com/doc/current/book/security.html一步一步地配置安全系统。 让这成为一种理解安全性的参考应用。

通过该过程结束时,我怀疑你会想通了这个问题,可以解决应用到现有的应用程序。 作为奖励,你将有一些可以参考的未来的问题。

================================================== ================

更新4日 - 激动人心的结论

所以,现在我们发现,正在使用的自定义和天真的登录系统。

我还是建议以一个新的项目重新开始,并把事情的工作的Symfony的2路。 在此之后,你可以调整登录表单使用JavaScript,如果你真的想。

如果你真的真的真的想用自己的系统,然后从这里开始: 手动认证用户

但是,你会被折腾出来的Symfony对无特殊原因的主要优势之一。



Answer 2:

它应该工作的方式是,Symfony的生成CSRF令牌,它自动插入到表单中。 它存储此令牌在当前会话中。 当提交表单时,它提交令牌与存储在会话中的值进行比较。 关于你提到的具体情况,它只是听起来像CSRF实际上并没有启用,它可能与没有受保护区域的防火墙,这使CSRF,登录防火墙,它不共享安全上下文做。

尝试删除您的security.yml此位:

login:
    pattern:  ^/demo/secured/login$
    security: false

而是,将它移入secured_area上下文和使用访问控制,授权访问:

...

form_login:
    check_path: _security_check
    login_path: login
...

access_control:
    - { path: ^/demo/secured/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

或者,你可以尝试添加context: secured_area您登录防火墙。 根据我的经验,没有在同样的情况下登录防火墙作为安全区域阻止你完全从你的登录控制器内访问的安全上下文。



文章来源: How does Symfony2 CRSF protection work?