CVE-2026-40372: ASP.NET Core 권한 상승 취약점 분석

서론

2026년 초, 한 금융권 시스템에서 발생한 보안 사고의 당황스러운 로그 기록을 상상해 보십시오. 외부에서 들어온 일반 사용자 권한의 요청이 명백히 관리자 전용으로 설정된 API 엔드포인트에 도달했음에도 불구하고, 서버는 “403 Forbidden” 대신 “200 OK"와 함께 민감한 고객 데이터를 반환했습니다. 방화벽은 정상 작동했고, JWT 토큰 검증도 통과된 것처럼 보였습니다. 문제는 애플리케이션의 가장 깊은 곳, 신뢰할 수 있는 경계(Trust Boundary)가 무너졌다는 점입니다.

이것이 바로 CVE-2026-40372가 현실화된 시나리오입니다. Microsoft가 긴급 패치를 배포한 이 ASP.NET Core의 권한 상승 취약점은 단순한 인증 우회를 넘어, 공격자가 인증된 사용자의 권한을 탈취하여 시스템 전체를 장악할 수 있는 치명적인 틈을 보여줍니다. 현대의 웹 애플리케이션이 복잡한 마이크로서비스 아키텍처로 발전하면서, 권한 검증 로직의 미세한 논리적 오류가 초래하는 파급력은 더욱 커지고 있습니다. 이 글에서는 이 취약점의 기술적 원리를 해부하고, 공격자가 이를 어떻게 악용하는지, 그리고 우리가 당장 취해야 할 방어 조치는 무엇인지를 심층적으로 분석합니다.

본론

기술적 원리: 엔드포인트 라우팅과 정책 평가의 결함

CVE-2026-40372의 핵심은 ASP.NET Core의 Endpoint RoutingAuthorization Middleware 구현 내부에 존재하는 논리적 결함에 있습니다. 일반적으로 ASP.NET Core는 요청이 컨트롤러에 도달하기 전에 UseAuthorization() 미들웨어를 통해 사용자의 접근 권한을 확인합니다.

문제는 특정 조건下에서 복합적인 라우팅 제약 조건(Constraints)과 정책(Policy)이 충돌할 때 발생합니다. 취약점이 있는 버전에서는 런타임 시점에 정책을 평가하는 IAuthorizationService가, 특정 메타데이터 병합(Metadata Merging) 과정에서 기본 정책(Fallback Policy)을 잘못 처리하거나, 암묵적인 AllowAnonymous 속성을 우선순위에 두는 오류를 범합니다. 이로 인해 [Authorize] 특성(Attribute)이 명시되어 있음에도 불구하고, 시스템은 요청을 “인증 불필요"로 잘못 해석하여 인가 체크를 완전히 건너뛰게 됩니다. 즉, 공격자는 정상적인 로그인 과정만 거치면 추가적인 권한 검증 없이 관리자 기능을 호출할 수 있게 됩니다.

취약점 공격 메커니즘 흐름

아래 다이어그램은 취약한 환경에서 공격자가 권한 상승을 수행하는 과정을 단순화하여 보여줍니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
graph LR
    A[Attacker Request] --> B[Authentication Middleware]
    B -->|Valid Token| C[Routing Middleware]
    C --> D[Endpoint Selection]
    D --> E[Authorization Middleware]
    E -->|Vulnerable Logic| F[Policy Bypass]
    F --> G[Admin Controller Action]
    G --> H[Sensitive Data Exposure]
    
    E -->|Normal Logic| I[403 Forbidden]

정상적인 흐름이라면 Authorization Middleware 단계에서 사용자의 Role(역할)이 ‘Admin’이 아님을 감지하고 403 Forbidden을 반환해야 합니다. 그러나 CVE-2026-40372가 활성화된 상태에서는 정책 평가 로직이 우회되어 Admin Controller Action이 직접 실행됩니다.

취약 코드 예시 및 분석

다음은 이 취약점의 영향을 받을 수 있는典型的인 ASP.NET Core 컨트롤러 코드입니다. 이 코드는 표준적인 방식으로 작성되었지만, 취약점이 패치되지 않은 환경에서는 심각한 보안 허점이 됩니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class SystemConfigController : ControllerBase
{
    // 관리자만 접근이 허용되어야 하는 설정 변경 엔드포인트
    [HttpPut("update-security-policy")]
    [Authorize(Roles = "Administrator")]
    public IActionResult UpdateSecurityPolicy([FromBody] PolicyModel model)
    {
        // 이 로직은 일반 사용자에게는 절대 실행되어서는 안 됩니다.
        // 하지만 CVE-2026-40372가 악용되면 일반 User 권한으로도 실행 가능해집니다.
        return Ok(new { Status = "Success", Message = "Security policy updated by admin." });
    }
}

public class PolicyModel 
{
    public string PolicyName { get; set; }
    public string Value { get; set; }
}

위 코드에서 [Authorize(Roles = "Administrator")] 속성은 명백하게 접근 제어를 의도합니다. 그러나 취약점을 trigger하는 특수한 HTTP 요청(예: 잘못 형성된 헤더나 특수 문자가 포함된 라우팅 값)이 전송되면, 프레임워크 내부의 정책 해석기가 이 속성을 무시하거나 충돌을 일으켜 권한 검증을 건너뜁니다.

영향 받는 버전 및 패치 현황

이 취약점은 다양한 .NET 환경에 영향을 미칩니다. 아래 표를 통해 현재 사용 중인 환경이 취약한지 확인하십시오.

| .NET 버전 | 취약한 버전 (Vulnerable) | 패치된 버전 (Patched) | 심각도 | | :— | :— | :— | :— | | .NET 8.0 | 8.0.0 ~ 8.0.7 | 8.0.8 이상 | Critical (치명적) | | .NET 9.0 | 9.0.0 ~ 9.0.0-rc.1 | 9.0.0-rc.2 이상 | Critical (치명적) | | .NET 6.0 | 6.0.0 ~ 6.0.32 (LTS) | 6.0.33 이상 | Important (중요) |

참고로 .NET 6.0은 표준 지원 기간이 종료되었으나, LTS(장기 지원) 고객을 위해 보안 업데이트가 제공되고 있습니다. 반드시 해당 버전으로 업데이트해야 합니다.

단계별 완화 및 대응 가이드

시스템을 즉시 보호하기 위해 다음의 절차를 따르십시오.

  1. 영향도 평가 (Impact Assessment) * 서버에서 dotnet --list-sdksdotnet --list-runtimes 명령어를 실행하여 설치된 런타임 버전을 확인합니다. * .csproj 파일의 <TargetFramework> 태그를 확인하여 프로젝트가 사용하는 버전을 점검합니다.

  2. 보안 업데이트 적용 (Patch Application) * 개발 환경 및 운영 환경의 모든 SDK 및 런타임을 ‘패치된 버전’ 이상으로 업그레이드합니다. * CI/CD 파이프라인이 있는 경우, 기본 Docker 이미지나 빌드 에이전트의 .NET 버전을 먼저 업데이트해야 합니다.

  3. 코드 레벨 방어 강화 (Defense in Depth) * 프레임워크 패치만으로는 완벽하지 않을 수 있으므로, 핵심 기능에 대해서는 컨트롤러 속성 외에도 명시적 코드 검증을 추가합니다.

1
2
3
4
5
6
7
8
9
[HttpPut("update-security-policy")]
[Authorize(Roles = "Administrator")]
public IActionResult UpdateSecurityPolicy([FromBody] PolicyModel model)
{
    // 방어적 코딩: 속성 외에도 명시적으로 권한 재확인
    if (!User.IsInRole("Administrator"))
    {
        // 의심스러운 활동 로깅
        _logger.LogWarning($"Unauthorized access attempt by user

출처: https://news.google.com/rss/articles/CBMigwFBVV95cUxQS0hHSFFybUJaZW5pbGg5MDJRMERyY04wRVpsT0owa1dkRFAzRkg5ZV9nYk1XVmIzM1RkTjdydnZ2ZVo1aDdmb0FDZUFjeEJSYXJ2Z1NTQ0RfSzIwS2FOMElpZ245dVBuaTNIbTRKTXdWWXE0QkFLUlB6MHdBQWZSOXgwTQ?oc=5

Hugo로 만듦
JimmyStack 테마 사용 중