Symfony2 CRSF保护如何工作? [英] How does Symfony2 CRSF protection work?

查看:64
本文介绍了Symfony2 CRSF保护如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试Symfony2完成的CRSF保护系统。

我的security.yml模板:(我修改了默认的。)

 安全性:

防火墙:
开发人员:
模式:^ /(__(profiler | wdt) | css | images | js)/
安全:假

登录:
模式:^ / demo / secured / login $
安全:假
secure_area:
模式:^ / demo / secured /
form_login:
check_path:_security_check
login_path:_demo_login
csrf_provider:form.csrf_provider
注销:
路径:_demo_logout
目标:_demo
#匿名:〜
#http_basic:
#领域:安全演示区

访问控制:
#-{路径:^ / login,角色:IS_AUTHENTICATED_ANONYMOUSLY,r equires_channel:https}

我的表单:

 <输入类型= hidden name = _ csrf_token value = {{csrf_token( authenticate)}}> 

生成的内容如下:

 <输入类型= hidden name = _ csrf_token value = cKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw> 

我不知道symfony如何使用令牌处理验证,但是在提交登录信息之前,我使用Firebug手动更改令牌的值,如下所示:

 < input type = hidden name = _ csrf_token  value = MODIFIEDcKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw> 

,当我提交登录名时,我就登录了。这意味着该令牌没有影响力。
我在哪里弄错了?






狙击狩猎


  1. Symfony版本为2.5.2

  2. 当我手动将会话变量 logged设置为true时,系统登录了我。从数据库读取并比较密码后,就会发生这种情况。

  3. 表单HTML!

     < form id = Loginform onsubmit = OrganicLogin();返回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占位符= 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>密码< / 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. 否..



解决方案

我有点猜测您更改的令牌没有被发布。坚持下去:

 命名空间Symfony\Component\Form\Extension\Csrf\CsrfProvider; 

类DefaultCsrfProvider实现CsrfProviderInterface
{
公共函数isCsrfTokenValid($ intention,$ token)
{
die('csrf token'。$ intention。 ''。$ token);
return $ token === $ this-> generateCsrfToken($ intention);
}

如果已经死了,那么您就知道您的配置还可以,当然您可以看到实际发布的令牌。



不用说,您也应该清除缓存。



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



更新1-经过多次注释,我们确定未调用die()。进度。



不幸的是,我们仍然需要确切验证发布者如何配置他们的系统。



下一步-登录时无需通过Firebug调整csrf令牌,并验证是否达到了die语句。



以一种或另一种方式报告。



无需赘言(但我还是会说),请确保您先注销,然后再尝试重新登录。



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



更新2-即使使用正常登录也无法达到die语句。



现在是我最喜欢的部分。狙击狩猎。基本上,在阅读问题时我做了很多假设。需要通过询问一些基本问题来确定哪些假设不正确。


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


  2. 您如何知道系统已登录您?您是否在使用调试工具栏,它是否显示您已通过身份验证?尝试使用错误的密码登录时会发生什么?


  3. 使用浏览器的查看源功能并将生成的表单复制到您的问题中。特别是,我希望看到action属性,但同时也希望看到输入元素。


  4. 实际上您是否将die语句添加到了vendor / symfony / symfony / src / Symfony / Component / Form / Csrf / CsrfProvider / DefaultCsrfProvider.php?您在编辑文件后保存了文件吗?


  5. 您实际上是在使用标准的form_login过程吗?您没有任何代码可以检查用户密码?


  6. 您是否还在使用其他捆绑软件,例如FOSUserBundle?


  7. 问题中的security.yml文件实际上是您的实际文件吗?复制后没有清理吗?


  8. 您是否已将应用程序签入github?如果可以,那么您可以提供一个链接吗?查看整个应用程序可能是清除此问题的最快方法。


到目前为止,这已经足够了。用答案更新您的问题。



============================ ============================== b
$ b

更新3-地块变粗



当我在上述问题中键入内容时,我们发现基本登录系统本身并不正确配置。调试工具栏指示用户未通过身份验证。更多进步!



安全系统可以说是典型开发人员需要与Symfony 2交互的最复杂的组件。进行配置时很容易感到困惑,并且很难进行故障排除。一个微小的错字可以使事情融化。对开发人员来说,有效地了解如何实施安全性也很重要。除非您当然不是像Target或Home Depot这样的真正大公司。



我的建议是使用作曲家创建一个新的Symfony 2项目。然后浏览 http://symfony.com/doc/current/book/security.html 逐步配置安全系统。让这成为了解安全性的参考应用程序。



到该过程结束时,我怀疑您已经解决了问题,可以将解决方案应用于现有应用程序。作为奖励,您会遇到一些将来遇到的问题。



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



更新4-令人兴奋的结论



因此,现在我们发现正在使用自定义且幼稚的登录系统。



我仍然建议从一个新项目重新开始,并使事情以Symfony 2的方式工作。之后,您可以根据需要调整登录表单以使用javascript。



如果您真的很想使用自己的系统,则从这里开始:手动验证用户身份



但是您将无缘无故抛弃Symfony的主要优势之一。


I'm trying to test the CRSF protection system done by Symfony2, many thanks to them.
my security.yml template:(I modified the default one.)

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 }

In my form :

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

That generates something like this:

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

I don't know how symfony handles the verifications with the token, but before submitting my login, I changed the value of the token manually using firebug to look like this:

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

and when I submit my login, I get logged in. which means the token has no influence . where am I getting wrong ?


Snipe hunting

  1. Symfony Version is 2.5.2
  2. The system signed me in when I set manually a session variable "logged" to true. This happens after Reading from the database and comparing the passwords.
  3. Form 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. Yes ! I did

  5. Actually that what I was arguing about the whole time, I did the login process in a native way, form, read data with JS, send POST request to controller, controller checks input and set the session.

  6. No, All done by hand

  7. Actually this is the first time I use security.yml, I just removed some parts I judged not useful for this thread

  8. no ..

解决方案

I'm sort of guessing that your changed token is not getting posted. Stick a die in:

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);
    }

If the die is reached then you know your configuration is okay and of course you can see the actual posted token.

Needless to say, you should also clearcache.

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

Update 1 - After many comments we have determined that the die() is not being called. Progress.

Unfortunately we still need to verify exactly how the poster has configured their system.

Next step - Login without adjusting the csrf token via firebug and verify that the die statement is reached.

Report one way or another.

Needless to say (but I will say it anyways), make sure you logout before trying to log back in.

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

Update 2 - The die statement is not being reached even with a normal login.

So now comes my favorite part. Snipe hunting. Basically, I made a number of assumptions when reading the question. Need to determine which assumptions were incorrect by asking a number of basic questions.

  1. Which version of Symfony 2 are you using. I am assuming at least S2.1.

  2. How do you know the system has signed you in? Are you using the debug toolbar and does it show you as being authenticated? What happens when you try to login with an incorrect password?

  3. Use your browser's view source functionality and copy the generated form into your question. In particular I want to see the action attribute but I also want to see the input elements.

  4. Did you in fact add the die statement to vendor/symfony/symfony/src/Symfony/Component/Form/Csrf/CsrfProvider/DefaultCsrfProvider.php? Did you save the file after editing it?

  5. You are in fact using the standard form_login process right? You don't have any code that, for example, checks the user password?

  6. Are you using any other bundles like maybe FOSUserBundle?

  7. The security.yml file in your question really is your actual file? You didn't "clean it up" after copying?

  8. Have you checked your application into github? If so then can you provide a link? Looking at the entire application will probably be the fastest way to clear this up.

That should be enough for now. Update your question with your answers.

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

Update 3 - The plot thickens

As I was typing in the above questions we discover that the basic login system itself is not properly configured. The debug toolbar indicated the user is not authenticated. More progress! As so often happens, the symptoms were masking the actual problem.

The security system is arguably the most complicated component in Symfony 2 that typical developers need to interact with. It's easy to get confused when configuring it and difficult to troubleshoot. One tiny typo can melt things down. It's also very important for the developer to have a working understanding of how security is implemented. Unless of course you are a really big company like Target or Home Depot.

My suggestion is to create a fresh Symfony 2 project using composer. Then go through http://symfony.com/doc/current/book/security.html step by step and configure the security system. Let this be kind of a reference application for understanding security.

By the end of the process I suspect you will have figured out the problem and can apply the solution to your existing application. As a bonus you will have something you can refer to for future problems.

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

Update 4 - The exciting conclusion

So now we find that a custom and naive login system is being used.

I would still suggest starting over with a new project and get things working the Symfony 2 way. After that, you can tweak the login form to use javascript if you really want to.

If you really really really want to use your own system then start here: Manual authenticate user

But you would be tossing out one of Symfony's major strengths for no particular reason.

这篇关于Symfony2 CRSF保护如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆