사용자 입력 기반 보안 검사 우회
Reliance on Untrusted Inputs in a Security Decision
설명
애플리케이션이 인증/권한을 사용자가 제어할 수 있는 입력값(쿠키, 헤더, 쿼리, 라우트 파라미터 등)에 의존할 때 발생합니다. 특히 서로 다른 사용자 입력끼리 비교해 로그인 여부나 접근 권한을 판단하면, 공격자가 해당 값을 임의로 조작해 보호된 기능이나 데이터에 접근할 수 있습니다. 예를 들어 role=admin 쿠키를 임의로 만들어 보내거나, 쿠키의 userId와 URL의 userId를 맞춰 보내는 식으로 인증을 우회할 수 있습니다.
잠재적 영향
인증 우회: 공격자가 로그인하지 않았거나 다른 사용자임에도 합법적인 사용자로 가장해 접근할 수 있습니다.
권한 상승/수평 이동: role, perm 같은 값을 조작하여 관리자 권한 획득 또는 다른 사용자의 리소스에 접근할 수 있습니다.
민감정보 유출: 개인 정보, 결제 정보, 내부 설정 등 보호된 데이터가 노출될 수 있습니다.
중요 기능 오남용: 관리자 전용 기능(설정 변경, 사용자 관리 등)을 무단 실행해 시스템을 손상시킬 수 있습니다.
해결 방법
서버가 제어하는 신뢰 가능한 값으로만 보안 결정을 하십시오: 서버 세션(req.session), 서명된 쿠키(req.signedCookies), 검증된 JWT의 클레임, DB 조회 결과 등을 사용합니다.
사용자 입력 간 교차 비교 금지: req.cookies.userId 와 req.params.userId 같은 두 개의 사용자 입력끼리 비교해 인증/권한을 판단하지 마십시오.
권한은 서버 기준으로 결정: userId로 DB에서 사용자/권한을 조회한 뒤, 서버가 정의한 권한 정책에 따라 접근을 허용합니다.
서명/검증 필수: 쿠키는 서명(signed) 또는 서버 세션을 사용하고, JWT는 서명 검증을 필수로 수행합니다. 단순한 평문 쿠키/파라미터를 신뢰하지 마십시오.
공통 미들웨어 도입: 인증(Auth)과 권한(Authorization) 검사를 미들웨어로 중앙화하여 모든 민감 라우트에 일관되게 적용합니다.
최소권한 원칙: 기능별로 필요한 최소 권한만 허용하고, 허용 목록(allowlist) 기반으로 체크합니다.
취약한 코드 및 안전한 코드 예시
취약한 코드
안전한 코드
설명:
취약한 코드: 쿠키(req.cookies.role, req.cookies.user)와 쿼리(req.query.user)는 모두 클라이언트가 조작할 수 있는 값입니다. 이 값들끼리 비교해 권한을 판단하면, 공격자는 role=admin 같은 쿠키를 임의로 설정하거나 쿼리 파라미터를 맞춰 보내 권한을 쉽게 우회할 수 있습니다.
안전한 코드: 서명된 쿠키(req.signedCookies.userId)로 서버가 값의 무결성을 검증하고, 해당 userId로 DB에서 사용자와 권한을 조회해 서버 기준으로 판단합니다. 사용자가 보낸 평문 입력끼리 비교하지 않으므로 값 조작에 의한 인증/권한 우회가 차단됩니다.
참조
Last updated