
Authorization Bypass란 인가 우회로 인증된 사용자가 의도된 권한 범위를 초과하여 시스템 자원에 접근하는 보안 취약점입니다
OWASP Top 10에서 1위를 차지한 Broken Access Control의 핵심 메커니즘으로 권한 상승의 대부분이 이 범주에 속합니다
인증을 나타내는 Authentication과 인가를 나타내는 Authorization에 대한 차이를 먼저 이해하는 것이 중요할 것이라고 생각됩니다
저도 계속 공부를 하고 있지만 아직도 헷갈리긴 합니다...
Authentication은 요청을 보내는 사람이 실제로 그 사람이 맞는지 확인하는 절차입니다
예를 들어 ID, 패스워드, 생체정보나 신분증 등을 검사하는 등의 절차를 말합니다
사용자는 로그인 화면에서 아이디와 비밀번호를 입력합니다
서버는 이 정보를 데이터베이스에 저장된 값과 비교합니다
일치한다면, 사용자가 올바른 자격을 가진 사람임을 인정합니다
이후 세션, 토큰 (JWT) 등의 방식으로 인증 상태를 유지합니다
인증 수단으로는 다양하게 존재합니다
다양한 범주로 나뉘지만 여기서는 이런 인증 수단들이 있다는 정도를 알아두시면 좋을 것 같습니다
ID / Password
OTP (One-Time Password)
인증 메일 / 인증 문자
Google, Kakao 등 OAuth 기반의 소셜 로그인
API Key
인증서 기반 인증 (ex. TLS client cert)
인증 우회는 인증 과정 자체를 건너뛰는 것으로 보안상으로 매우 위험합니다
예시로는 아래와 같습니다
SQL Injection으로 비밀번호 검증 없이 로그인 성공
디버깅을 위한 로그인 우회 파라미터가 외부에 노출
잘못된 인증 로직으로 is_admin=true 같은 값만 넘겨도 인증됨
Authorization은 인증이 완료된 사용자에 대해 특정 자원 (Resource)이나 기능 (Function)에 대한 접근을 허용할 것인지 판단하는 절차입니다
예를 들어 건물 안에 들어온 사람이 특정한 곳으로 들어가려고 할 때 관리자가 들어갈 권한이 있는지 확인합니다
이 권한을 확인하고 허용하는 것이 바로 인가입니다
예를 들어 로그인 된 사용자가 아래와 같은 요청을 보냈다고 가정해봅시다
그렇다면 서버는 아래의 내용들을 확인해야합니다
이렇게 인가는 역할, 소속, 등급, 리소스 소유권 등에 따라 결정됩니다
인가 방식에는 여러 유형이 있으며 각각 목적 및 활용 맥락이 다릅니다
아래는 주요 인가 방식입니다
역할 기반 접근 제어는 사용자에게 직접 권한을 부여하는 것이 아니라 사용자가 가진 역할 (Role)에 따라 권한을 부여하는 방식입니다
권한 관리가 간단하고 직관적이며 사용자 수가 많을 때 효과적입니다
단점으로는 역할이 많아지면 관리가 복잡하다는 것입니다
속성 기반 접근 제어는 접근 제어를 사용자, 리소스, 환경의 속성 (Attribute)을 기반으로 결정하는 방식입니다
매우 유연하고 세밀한 정책 구성이 가능하며 확장성이 높습니다
하지만 정책 설계 및 관리가 복잡하며 속성 정보가 정확해야 합니다
정책 기반 접근 제어는 ABAC와 유사하나 정책 단위로 인가를 정의하고 평가하는 데 중점을 둡니다
행위 가능 여부를 미리 정의된 정책 (Policy)에 따라 판단합니다
실제로는 XACML 같은 표준으로 구현되기도 하며 클라우드 환경에서 많이 사용됩니다
강제 접근 제어는 보안 등급에 따라 운영체제나 시스템이 일괄적으로 접근을 제어하는 방식입니다
군사 시스템이나 정부 시스템에서 많이 사용됩니다
매우 강력하고 엄격한 보안이 가능한 것이 장점입니다
하지만 유연성이 별로 없고 일반 기업 시스템에는 부적합합니다
임의 접근 제어는 리소스를 소유한 사용자 (Owner)가 접근 권한을 다른 사용자에게 줄 수 있는 방식입니다
단순하고 빠른 접근 제어가 가능한 것이 장점입니다
단점은 보안 일관성 유지가 어렵고 권한의 무분별한 확장이 발생할 수 있습니다
JWT / Token 기반 인가는 사용자가 로그인한 후 서버가 발급한 토큰 안에 권한 정보를 포함해 이 토큰을 이용해 자원 접근을 제어하는 방식입니다
Stateless 인가가 가능하고 마이크로서비스나 API 시스템에 적합합니다
인가 우회는 보통 아래의 상황에서 발생합니다
사용자가 인증은 되었지만, 특정 리소스에 접근할 권한이 없을 때
서버가 자원에 대한 권한 검사를 제대로 하지 않을 때
클라이언트 측 정보(예: role, isAdmin 등)를 신뢰할 때
Authorization Bypass에 대한 주요 기법을 알아봅시다
인증된 사용자가 단순히 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 조작된 토큰
이는 서버가 토큰의 서명을 검증하지 않거나 클라이언트 데이터를 신뢰할 때 발생합니다
리소스에 대해 GET, POST, PUT, DELETE 등 HTTP 메서드에 따라 동작이 달라질 수 잇습니다
권한 검사를 일부 메서드에만 적용한 경우에 우회가 가능합니다
/article/1에 대해 DELETE는 관리자만 가능하지만 POST /article/1?_method=DELETE처럼 변조하면 삭제가 가능한 것이 예시입니다
프론트엔드 / 백엔드가 분리된 환경에서 API 단위의 권한 검사가 미흡할 때 발생합니다
모바일 앱에는 제한된 기능만 노출되지만 API 서버는 모든 요청을 허용하는 것이 예시입니다
다음은 방어 기법입니다
서버는 요청을 수행한 사용자가 해당 리소스에 대한 권한이 있는지를 무조건 서버 로직에서 확인해야 합니다
아래는 예시입니다
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
});
RBAC / ABAC 등의 인가 모델을 적용하여 기능별 또는 자원별 권한 제어를 체계화해야 합니다
관리 기능: admin role만 접근 가능
글 작성: editor, admin만 가능
특정 API: scope: wirte:posts 필요
OWASP, ZAP, Burp Suite 등을 이용해 인가 우회 시도를 자동 혹은 수동으로 점검해야 합니다
실수하기 쉬운 인가 로직을 테스트 케이스로 명시합니다
UI에서 관리자 전용 기능을 숨기더라도 URL을 알고 직접 요청하면 실행되는 경우가 많습니다
백엔드에서 반드시 Role 검사가 필요합니다
권한이 없는 사용자가 요청 시 로그로 기록합니다
반복적으로 접근 시 차단 또는 알림이 필요합니다
오늘은 간단하게 Authorization Bypass에 대해 알아봤습니다
Authorization과 Authentication 모두 용어의 의미로는 안 헷갈리겠다고 생각했는데 막상 글을 찾아보면서 정리하다보니 Authorization에 대해 하고 있는 것인지 Authentication에 대해 하고 있는 것인지 헷갈리기도 했습니다
그래도 조금은 덜 헷갈릴 것 같습니다!