Authorization Bypass에 대해 알아보기

맑음·2025년 5월 20일
post-thumbnail

Authorization Bypass란?

Authorization Bypass인가 우회로 인증된 사용자가 의도된 권한 범위를 초과하여 시스템 자원에 접근하는 보안 취약점입니다
OWASP Top 10에서 1위를 차지한 Broken Access Control의 핵심 메커니즘으로 권한 상승의 대부분이 이 범주에 속합니다

Authentication VS Authorization

인증을 나타내는 Authentication과 인가를 나타내는 Authorization에 대한 차이를 먼저 이해하는 것이 중요할 것이라고 생각됩니다
저도 계속 공부를 하고 있지만 아직도 헷갈리긴 합니다...

Authentication

Authentication은 요청을 보내는 사람이 실제로 그 사람이 맞는지 확인하는 절차입니다
예를 들어 ID, 패스워드, 생체정보나 신분증 등을 검사하는 등의 절차를 말합니다

웹에서의 Authentication

  • 사용자는 로그인 화면에서 아이디와 비밀번호를 입력합니다

  • 서버는 이 정보를 데이터베이스에 저장된 값과 비교합니다

  • 일치한다면, 사용자가 올바른 자격을 가진 사람임을 인정합니다

  • 이후 세션, 토큰 (JWT) 등의 방식으로 인증 상태를 유지합니다

인증 수단

인증 수단으로는 다양하게 존재합니다
다양한 범주로 나뉘지만 여기서는 이런 인증 수단들이 있다는 정도를 알아두시면 좋을 것 같습니다

  • ID / Password

  • OTP (One-Time Password)

  • 인증 메일 / 인증 문자

  • Google, Kakao 등 OAuth 기반의 소셜 로그인

  • API Key

  • 인증서 기반 인증 (ex. TLS client cert)

인증 우회

인증 우회는 인증 과정 자체를 건너뛰는 것으로 보안상으로 매우 위험합니다

예시로는 아래와 같습니다

  • SQL Injection으로 비밀번호 검증 없이 로그인 성공

  • 디버깅을 위한 로그인 우회 파라미터가 외부에 노출

  • 잘못된 인증 로직으로 is_admin=true 같은 값만 넘겨도 인증됨

Authorization

Authorization은 인증이 완료된 사용자에 대해 특정 자원 (Resource)이나 기능 (Function)에 대한 접근을 허용할 것인지 판단하는 절차입니다
예를 들어 건물 안에 들어온 사람이 특정한 곳으로 들어가려고 할 때 관리자가 들어갈 권한이 있는지 확인합니다
이 권한을 확인하고 허용하는 것이 바로 인가입니다

웹에서의 Authorization

예를 들어 로그인 된 사용자가 아래와 같은 요청을 보냈다고 가정해봅시다

  • /admin/delete_user/123
  • /user/42/transactions

그렇다면 서버는 아래의 내용들을 확인해야합니다

  • 이 사용자가 admin 권한을 가지고 있는가?
  • 이 사용자가 ID가 42인 계정의 거래내역을 볼 수 있는 사용자 본인인가?

이렇게 인가는 역할, 소속, 등급, 리소스 소유권 등에 따라 결정됩니다

인가 방식

인가 방식에는 여러 유형이 있으며 각각 목적 및 활용 맥락이 다릅니다
아래는 주요 인가 방식입니다

RBAC (Role-Based Access Control)

역할 기반 접근 제어는 사용자에게 직접 권한을 부여하는 것이 아니라 사용자가 가진 역할 (Role)에 따라 권한을 부여하는 방식입니다
권한 관리가 간단하고 직관적이며 사용자 수가 많을 때 효과적입니다
단점으로는 역할이 많아지면 관리가 복잡하다는 것입니다

ABAC (Attribute-Based Access Control)

속성 기반 접근 제어는 접근 제어를 사용자, 리소스, 환경의 속성 (Attribute)을 기반으로 결정하는 방식입니다
매우 유연하고 세밀한 정책 구성이 가능하며 확장성이 높습니다
하지만 정책 설계 및 관리가 복잡하며 속성 정보가 정확해야 합니다

PBAC (Policy-Based Access Control)

정책 기반 접근 제어는 ABAC와 유사하나 정책 단위로 인가를 정의하고 평가하는 데 중점을 둡니다
행위 가능 여부를 미리 정의된 정책 (Policy)에 따라 판단합니다
실제로는 XACML 같은 표준으로 구현되기도 하며 클라우드 환경에서 많이 사용됩니다

MAC (Mandatory Access Control)

강제 접근 제어는 보안 등급에 따라 운영체제나 시스템이 일괄적으로 접근을 제어하는 방식입니다
군사 시스템이나 정부 시스템에서 많이 사용됩니다
매우 강력하고 엄격한 보안이 가능한 것이 장점입니다
하지만 유연성이 별로 없고 일반 기업 시스템에는 부적합합니다

DAC (Discretionary Access Control)

임의 접근 제어는 리소스를 소유한 사용자 (Owner)가 접근 권한을 다른 사용자에게 줄 수 있는 방식입니다
단순하고 빠른 접근 제어가 가능한 것이 장점입니다
단점은 보안 일관성 유지가 어렵고 권한의 무분별한 확장이 발생할 수 있습니다

JWT / Token 기반 인가

JWT / Token 기반 인가는 사용자가 로그인한 후 서버가 발급한 토큰 안에 권한 정보를 포함해 이 토큰을 이용해 자원 접근을 제어하는 방식입니다
Stateless 인가가 가능하고 마이크로서비스나 API 시스템에 적합합니다

Authorization Bypass 공격 유형

인가 우회는 보통 아래의 상황에서 발생합니다

  • 사용자가 인증은 되었지만, 특정 리소스에 접근할 권한이 없을 때

  • 서버가 자원에 대한 권한 검사를 제대로 하지 않을 때

  • 클라이언트 측 정보(예: role, isAdmin 등)를 신뢰할 때

Authorization Bypass에 대한 주요 기법을 알아봅시다

URL / 파라미터 조작 (Direct Object Reference)

인증된 사용자가 단순히 URL의 매개변수를 변경해 다른 사용자의 자원에 접근하는 방식입니다
종종 Insecure Direct Object Reference (IDOR)와 연결됩니다

아래는 간단한 예시입니다

GET /user/profile?id=1001  ← 일반 사용자 A의 프로필
GET /user/profile?id=1002  ← 권한 없는 사용자 B가 A의 정보에 접근

서버가 id와 로그인된 사용자 정보를 비교하지 않고 단순히 id=1002이면 해당 데이터를 그대로 보여주는 것이 문제입니다

숨겨진 기능 접근

UI에서는 버튼이 없지만, 실제로는 특정 URL을 직접 요청하여 기능을 실행하는 방식입니다
일반 사용자에게는 삭제 버튼이 없으나 /admin/delete_user?id=5 를 직접 호출하면 실행이 되는 것을 예시로 들 수 있습니다
이는 서버가 요청자의 권한을 검사하지 않고 기능을 수행하는 것이 문제입니다

클라이언트 측 정보 조작

클라이언트 측 쿠키, localStorage, JWT 토큰 등에서 인가 정보를 포함하고 이를 조작해 권한을 상승시키는 방식입니다

아래는 간단한 예시입니다

localStorage.setItem("role", "admin")

또는

Authorization: Bearer eyJhbGciOi...eyJyb2xlIjoiYWRtaW4ifQ== ← role 조작된 토큰

이는 서버가 토큰의 서명을 검증하지 않거나 클라이언트 데이터를 신뢰할 때 발생합니다

HTTP 메서드 변조

리소스에 대해 GET, POST, PUT, DELETE 등 HTTP 메서드에 따라 동작이 달라질 수 잇습니다
권한 검사를 일부 메서드에만 적용한 경우에 우회가 가능합니다
/article/1에 대해 DELETE는 관리자만 가능하지만 POST /article/1?_method=DELETE처럼 변조하면 삭제가 가능한 것이 예시입니다

미흡한 API 권한 분리

프론트엔드 / 백엔드가 분리된 환경에서 API 단위의 권한 검사가 미흡할 때 발생합니다
모바일 앱에는 제한된 기능만 노출되지만 API 서버는 모든 요청을 허용하는 것이 예시입니다

Authorization Bypass 방어 기법

다음은 방어 기법입니다

서버 측 인가 검사를 반드시 수행

서버는 요청을 수행한 사용자가 해당 리소스에 대한 권한이 있는지를 무조건 서버 로직에서 확인해야 합니다

아래는 예시입니다

def get_user_profile(request, id):
    if request.user.id != id and not request.user.is_admin:
        return "403 Forbidden"

클라이언트 정보 신뢰 금지

클라이언트엣서 넘어오는 role, 권한, user_id 등의 정보는 절대 신뢰하지 말고 세션, DB, 토큰 검증을 통해 서버가 스스로 확인해야 합니다

리소스 소유자 확인

특히 중요한 데이터 요청 시, 요청한 사용자와 데이터의 소유자가 일치하는지 검증이 필요합니다

아래는 예시입니다

app.get('/profile/:id', (req, res) => {
    if (req.user.id !== req.params.id) {
        return res.status(403).send("Forbidden");
    }
    // fetch and return profile
});

Role / Permission 체계 도입

RBAC / ABAC 등의 인가 모델을 적용하여 기능별 또는 자원별 권한 제어를 체계화해야 합니다

  • 관리 기능: admin role만 접근 가능

  • 글 작성: editor, admin만 가능

  • 특정 API: scope: wirte:posts 필요

보안 테스트 및 점검

OWASP, ZAP, Burp Suite 등을 이용해 인가 우회 시도를 자동 혹은 수동으로 점검해야 합니다
실수하기 쉬운 인가 로직을 테스트 케이스로 명시합니다

민감 기능은 UI 숨김만 하지 말고 서버 차단

UI에서 관리자 전용 기능을 숨기더라도 URL을 알고 직접 요청하면 실행되는 경우가 많습니다
백엔드에서 반드시 Role 검사가 필요합니다

보안 로그 기록 및 모니터링

권한이 없는 사용자가 요청 시 로그로 기록합니다
반복적으로 접근 시 차단 또는 알림이 필요합니다

마무리

오늘은 간단하게 Authorization Bypass에 대해 알아봤습니다
Authorization과 Authentication 모두 용어의 의미로는 안 헷갈리겠다고 생각했는데 막상 글을 찾아보면서 정리하다보니 Authorization에 대해 하고 있는 것인지 Authentication에 대해 하고 있는 것인지 헷갈리기도 했습니다
그래도 조금은 덜 헷갈릴 것 같습니다!

profile
내일도 맑음

0개의 댓글