회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업들의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업들의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?
이번 글은 ‘전 세계 사람들에게 즐거움을 선사하자’는 비전을 바탕으로 게임을 만들고 있는 ‘넷마블’의 보안개발팀 이야기입니다. 도대체 ‘/’ 구분자가 뭐길래 API 서버를 위협하는 지, 그 배경과 대처 방법에 대해 알아봅니다.
안녕하세요, 보안개발팀 전희창입니다. 오늘 소개할 취약점은 스프링 프레임워크 기반 RESTful API 서버 환경에서 발생하는 취약점입니다.
최초 공개: 2016년 7월 7일
CVE-2016-5007 취약점은 2016년 7월 7일에 최초 공개됐습니다. 어느덧 최초 공개일로부터 5년이 훌쩍 지났습니다. 하지만 최근까지도 스프링 프레임워크 기반 RESTful API 서버를 사용하는 여러 서비스에서 심각한 보안 위협이 발견되고 있어 연구 과제로 선정했습니다.
스프링 시큐리티(Spring Security)는 스프링에서 애플리케이션 인증과 권한 부여 같은 보안 기능을 제공하는 하위 프레임워크입니다. CVE-2016-5007 취약점은 스프링 시큐리티가 지원하는 권한 검증과 URL 패턴 검사 로직을 우회하도록 허용시켜서 접근 권한 관리를 무력화시킵니다. 즉, 접근 권한이 없는 URL에 우회 접근할 수 있다는 의미입니다.
특히 스프링 시큐리티에서 취약한 함수를 사용한다면, 버전에 상관없이 취약점이 발생한다는 점만으로도 매우 위협적인 부분이라고 할 수 있습니다.
스프링 프레임워크는 자바(Java) 기반 동적 웹 프레임워크로, 웹 개발에서 널리 사용하고 있습니다. 스프링 프레임워크는 하위 프레임워크인 스프링 시큐리티를 통해 보안 기능을 제공하며, RESTful API도 지원합니다.
RESTful API란 REST(Representational State Transfer) 아키텍처 디자인 원칙을 따르는 API로 HTTP 통신 프로토콜을 사용합니다. 어떤 플랫폼이든지 API 규칙에 맞춰서 요청하면 서버에서 리소스를 응답받을 수 있어 다양한 웹 서비스에서 사용하고 있습니다. 공공기관 홈페이지나 주요 포털 사이트에서 제공하는 OPEN API가 REST 아키텍처를 사용하고 있습니다. 그래서 이를 활용해 다양한 클라이언트나 서버 환경에서 OPEN API 리소스를 활용할 수 있습니다.
RESTful API 설계 규칙에서는 URI값에 슬래시(/) 구분자를 삽입하는 방법으로 계층을 구분합니다. 또한, URI값은 유일한 식별자로 사용해야 하므로, 맨 끝은 혼동을 주지 않도록 반드시 문자로 끝나야 합니다. 만약 계층 구분용으로 사용해야 하는 슬래시(/)를 URI값 맨 끝에 넣는다면 부정확한 값으로 인식돼 혼동을 줄 수 있습니다.
스프링 프레임워크 기반 RESTful API 서버라면 스프링 시큐리티로 URI 규칙을 미리 등록해두는 방식으로 접근 제어 규칙을 설정합니다. 그래서 사용자가 자원을 요청하면 미리 등록한 접근 제어 규칙과 매칭해서 허용 또는 차단을 결정합니다.
위 두 가지 특징으로 인해 RESTful API 서버에 인증 또는 인가한 사용자만 접근할 수 있는 자원을 요청하는 URI값 맨 끝에 슬래시(/)를 붙이면, 스프링 시큐리티의 접근 제어 규칙을 우회하는 틈이 생깁니다. 이 틈을 파고들면 허가받지 않은 사용자가 내부 자원에 접근할 수 있습니다. (내부 자원에 접근할 수 있는 만큼, 중요 정보를 조회하고 유출할 가능성이 생긴다고 할 수 있습니다.)
이 취약점은 기본적으로 스프링 시큐리티 접근 제어 규칙을 화이트리스트 기반으로 설정하면 막을 수 있습니다. 하지만 서비스 운영상 불가피하게 블랙리스트 기반으로 규칙을 사용해야 한다면, URI값 맨 끝에 붙인 슬래시(/)로 접근 제어 규칙 우회를 불가능하도록 설정해야 합니다.
화이트리스트와 블랙리스트 화이트리스트는 허용하는 조건 이외에는 모두 차단하는 접근 제어 방식입니다. 반대로, 블랙리스트는 차단하는 조건 이외에는 모두 허용하는 접근 제어 방식입니다. |
블랙리스트 기반 규칙인 경우, 아래 두 예시를 기준으로 취약한 버전과 안전한 버전을 비교해보겠습니다.
// 잘못된 설정 예시.antMatchers(HttpMethod.GET, "/api/admins").hasRole("ADMIN")// 올바른 설정 예시.antMatchers(HttpMethod.GET, "/api/admins/**").hasRole("ADMIN")
취약한 버전의 서버 환경 조건은 아래와 같습니다.
서버 환경
|
블랙리스트 기반 접근 제어 방식에서는 ‘/api/admins/’라는 URI로 요청이 올 경우, 스프링 시큐리티의 ‘antMatchers’ 함수에서 ‘/api/admins’와 문자열을 비교해 서로 일치하지 않는 것으로 판단하고 차단(deny)으로 넘어가야 합니다. 하지만 REST 아키텍처 규칙상 URI 끝에는 슬래시(/)가 붙지 않아야 하므로, ‘/api/admins/’ URI 요청을 ‘/api/admins’로 인식해버려 접근을 허용해버립니다. 이런 상황이라면 비인증 상태로도 내부 자원에 접근할 수 있습니다.
아래 화면은 최초에는 비인증 상태일 때 API 요청을 해도 자원에 접근할 수 없었으나, URI 끝에 슬래시(/)를 삽입해 비인증 상태임에도 자원에 접근한 공격 결과입니다.
화이트리스트 기반 접근 제어는 스프링(Spring) 측 공식 가이드에도 올라온 내용입니다. 접근할 수 있는 URI만 명시하고, 그 외 모든 URI는 인증이나 권한을 검증해야 합니다.
블랙리스트 기반에서는 URI 끝에 와일드카드
블랙리스트 기반 접근 제어를 사용해야 한다면, URI 입력 규칙에서 인증 및 권한 검증이 필요한 URI 끝에 와일드카드(/**)를 붙여야 합니다.
mvcMatchers 함수 사용
스프링 시큐리티에서는 ‘antMatchers’ 함수가 가진 취약점을 보완하기 위해, 보안 기능을 추가한 ‘mvcMatchers’ 함수를 제공하고 있습니다. ‘mvcMatchers’ 함수를 사용해 ‘/api/admin’을 설정하면 ‘/api/admin/’, ‘/api/admin.html’, ‘/api/admin.xyz’ 모두 매핑할 수 있습니다.
안전한 버전으로 조치를 마치면, URI 끝에 슬래시(/)를 삽입해도 접근 제어 우회가 불가능한 것을 확인할 수 있습니다.
서비스를 운영하다 보면, 레퍼런스에 맞춰서 화이트리스트 접근 제어 방식만 고집하기는 쉽지 않을 것입니다. 규칙으로 정의한 값을 꾸준히 업데이트하고, 접근하는 URI 매칭 로직에 와일드카드를 적절히 활용해 융통성과 보안성이라는 두 마리 토끼를 모두 꼭 잘 챙기셨으면 좋겠습니다.
<원문>