Symfony 的安全漏洞(命中受保护的端点总是返回未经授权的)

Posted

技术标签:

【中文标题】Symfony 的安全漏洞(命中受保护的端点总是返回未经授权的)【英文标题】:Security Bug with Symfony (Hitting Protected Endpoint Always Returns Unauthorized) 【发布时间】:2021-10-18 04:37:06 【问题描述】:

我有以下 config/packages/security.yml 文件,它实际上如下所示:

framework:
    rate_limiter:
        username_ip_login:
            policy: token_bucket
            limit: 5
            rate:  interval: '5 minutes' 

        ip_login:
            policy: sliding_window
            limit: 50
            interval: '15 minutes'

    services:
        app.login_rate_limiter:
            class: Symfony\Component\Security\Http\RateLimiter\DefaultLoginRateLimiter
            arguments:
                $globalFactory: '@limiter.ip_login'
                $localFactory: '@limiter.username_ip_login'

    security:
        enable_authenticator_manager: true
        password_hashers:
            App\Entity\User:
                algorithm: auto

        providers:
            app_user_provider:
                entity:
                    class: App\Entity\User
                    property: email
        firewalls:
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
                login_throttling:
                    max_attempts: 3
                    interval: '15 minutes'
                    limiter: app.login_rate_limiter
            main:
                lazy: true
                provider: app_user_provider
                login_throttling:
                    max_attempts: 3
                    interval: '15 minutes'
                    limiter: app.login_rate_limiter
                json_login:
                    check_path: /login
                    username_path: email
                    password_path: password
                custom_authenticators: 
                    - App\Security\TokenAuthenticator
                entry_point: App\Security\EntryPointAuth
                stateless: true

        access_control:
            -  path: ^/profile, roles: ROLE_USER 
            -  path: ^/books, roles: ROLE_USER 

这是我的控制器:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\SerializerInterface;

class ProfileController extends AbstractController


    private SerializerInterface $serializer;

    public function __construct(SerializerInterface $serializer)
    
        $this->serializer = $serializer;
    

    #[Route('/profile', name: 'get_profile', methods: ["GET"])]
    public function index(): JsonResponse
    
        $user = $this->getUser();

        $result = $this->serializer->serialize($user, 'json', ['groups' => ['read']]);

        return JsonResponse::fromJsonString($result);
    

    #[Route("/profile", name: "update_profile", methods: ["PUT"])]
    public function update(): JsonResponse
    
        echo 2;
        exit;
    

现在当我点击 GET /profile 时它成功了 但是当我点击 PUT /profile 进行更新时,它给了我 410 未经授权的响应。

我使用访问令牌无状态实现来确保安全,并且受保护的端点 GET /profile 运行良好,为什么即使我对两个端点使用相同的令牌,PUT /profile 也不起作用?

有什么想法吗?将不胜感激。

【问题讨论】:

您尝试过什么来解决问题?你被困在哪里了?您的应用程序的日志文件是否提供了更多详细信息? 问题是这 2 条受保护的路由 1 PUT 和 1 GET,GET 路由正常工作,使用访问令牌没有任何问题,正如您在控制器中看到的那样,但是当我点击它时 PUT 路由使用相同的访问令牌,我得到 410 未授权。 这里有一些日志: GET 请求成功如下: [Web Server ] Aug 16 20:59:56 |INFO | SERVER GET (200) /profile ip="::1" 但是 PUT 请求失败如下: [Web Server ] Aug 16 20:59:50 |WARN |服务器 PUT (401) /profile host="127.0.0.1:8004" ip="::1" scheme="https" 感谢@NicoHaase 我找到了解决方案 【参考方案1】:

我必须通过将 PUT 路由更改为配置文件/更新而不只是配置文件来管理它,因为它会产生冲突。我认为这是 Symfony 中需要解决的错误。

或者你需要把/profile的访问控制路由改成如下:

-  path: ^/profile, roles: ROLE_USER, methods: [GET, PUT] 

【讨论】:

如果您认为这是一个错误,请在 Symfony 的问题跟踪器中打开错误报告以修复此问题 是的,我会的。谢谢@NicoHaase

以上是关于Symfony 的安全漏洞(命中受保护的端点总是返回未经授权的)的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 2,未定义的变量,在构造函数中初始化为 ArrayCollection 的受保护成员通过错误,它是未定义的

javascript 示例登录并获取受保护的端点

使用受保护的 GraphQL 端点进行用户注册

如何在 Android 中打印受 Auth0-JWT 保护的私有 API 端点 JSON 对象?

为啥 symfony2 安全选民总是被召唤?

Symfony 2 安全总是返回 Bad Credentials 错误