시큐어코딩
- home
- 보안소식
- 시큐어코딩
11. [입력 데이터 검증 및 표현] HTTP 응답분할
2018.05.10 10:40
안녕하세요, 지에스인포입니다.
이번에는 행자부 개발보안 가이드라인 47개 항목 중 입력 데이터 검증 및 표현의 11번째 항목인 'HTTP 응답 분할'에 대해 알아보겠습니다.
HTTP 응답 분할은 행정자치부에서 발표한 '소프트웨어 개발보안 가이드'에 속해있는 주요 항목입니다. 분석, 설계 단계의 보안 요구항목에서는 '입력 데이터 검증 및 표현'의 'HTTP 프로토콜 유효성 검증'이라는 항목으로, 구현 단계 보안약점에서는 '입력 데이터 검증 및 표현'의 'HTTP 응답 분할'이라는 이름으로 명시가 되어있습니다.
#HTTP 응답 분할이란?
HTTP 응답 분할이란 HTTP 요청에 들어 있는 파라미터가 HTTP 응답 헤더에 포함되어 사용자에게 다시 전달될 때, 입력값에 CR(Carriage Return)이나 LF(LineFeed)와 같은 개행문자가 존재하면 HTTP이 2개 이상 분리될 수 있는데, 이 경우에 공격자가 개행문자를 이용하여 첫 번째 응답을 종료시키고 두 번째 응답에 악의적인 코드를 주입하여 XSS 및 캐시 훼손(Cache Poisoning) 공격 등을 수행할 수 있는 보안약점입니다.
HTTP 프로토콜은 크게 헤더와 바디, 2영역으로 나뉠 수 있습니다.
헤더는 서버와 클라이언트 사이에서 일반 문서 데이터 이외의 추가적인 정보를 교환할 수 있도록 선두에 삽입되는 요소이고, 바디는 실제 데이터가 입력되는 영역입니다.
헤더와 바디 사이에는 개행문자인 CR과 LF을 이용한 공백 라인이 존재하고, 이 공백 라인으로 헤더와 바디를 구분 짓습니다.
사실, 헤더의 한 줄 한 줄 또한 개행문자로 나뉠 수 있습니다.
만약, 요청 패킷의 헤더 부분에 입력된 데이터가 그대로 응답 패킷의 헤더에 담기게 되어 돌아온다면 HTTP 응답 분할 공격이 이루어질 수 있습니다.
예를 들어 살펴보겠습니다.
어떤 가상의 홈페이지에서 로그인을 하게 되면 로그인 한 유저의 ID(외부 입력 값)를 이용해 쿠키를 생성하여 응답 패킷의 헤더에서 사용하는 로직을 사용하고 있습니다. 위 소스 코드를 살펴보면, 2번 줄에서 getParameter 메서드를 이용해 사용자 ID(userID)를 변수에 저장하고, 7번째 줄에서 현재 날짜와 시간을 계산하여 time 변수에 저장합니다. 그리고 12번째 줄에서 저장한 userid와 time 이용해 생성할 쿠키의 값을 만들고, Cookie c를 생성합니다. 그리고 마지막으로 16번째 줄에서 response.addCookie(c)로 생성한 쿠키를 응답 헤더에 설정합니다.
victim이라는 유저가 로그인하였을 경우 (정상)
왼쪽 그림은 위의 소스 코드로 구현한 로그인 페이지에 victim이라는 사용자가 로그인했을 때의 응답 패킷입니다. 위에서 설명했다시피 응답 헤더의 각 항목들은 각각의 라인으로 구별되고 있습니다. 응답 헤더 부분을 보면 사용자 ID(victim)과 시간(20180129165133)이 조합되어 생성된 쿠키가 존재하는 것을 확인할 수 있습니다.
이를 통해 ID 부분에 입력한 외부 입력 값이 응답 헤더에서 사용하고 있다는 것을 알 수 있습니다.
위에서 헤더와 바디를 나누는 경계가 개행문자라고 설명하였는데, 그렇다면 공격자가 사용자 아이디에 개행문자들을 입력하게 된다면 어떻게 될까요?
개행문자를 이용해 응답 헤더를 분할시킨 결과
왼쪽의 그림을 보면 공격자가 입력한 값 중 검은색 문구는 평문, 빨간색으로 표시된 %0d%0a는 개행문자로써 응답 헤더의 각 항목 또는 헤더와 바디를 나누기 위해 사용된 것이고, 주황색으로 표시된 %20은 URL 인코딩 형태의 띄어쓰기입니다.
입력 값을 잘 살펴보면, 공격자는 응답 헤더의 Cookie에 선언될 hacker라는 값 뒤에 개행문자를 입력함으로써 Cookie 다음의 헤더 항목을 인위적으로 생성하였고, 다음 항목에 Content-Length: 0을 입력하였습니다. Content-Length란, 응답 바디에 실제로 들어가는 데이터의 크기를 의미하는데, 0으로 지정함으로써 바디가 존재하지 않게 되는 것입니다.
그리고 나서 공백 라인 2줄을 추가하여 새로운 헤더를 생성하고 그 헤더에 들어갈 항목들을 입력합니다. 헤더를 다 입력한 후 다시 공백 라인 2줄을 추가하여 응답 바디로 넘어와서 응답 값에 출력될 내용들을 입력하는데, 이곳에 스크립트 형태의 공격 문구를 입력하였고, 실제로 응답 패킷이 클라이언트로 넘어와 출력될 때 스크립트가 실행됩니다.
#HTTP 응답 분할을 막기 위한 보안 대책은?
HTTP 응답 분할을 방어하기 위한 대책은 소프트웨어 개발 생명 주기에 따라 크게 두 가지로 나눌 수 있습니다.
소프트웨어 개발보안 가이드에서 제시하는 "HTTP 응답 분할"에 대한 보안대책은 위와 같으며, 각각의 상황에 맞게 적절히 시큐어코딩을 적용하기를 권장하고 있습니다.
오늘은 "HTTP 응답 분할"에 대해 살펴봤습니다.
다음은 시큐어코딩 12번째 항목, "정수형 오버플로우"에 대해 알아보도록 하겠습니다.
댓글 0
본사주소 : 서울특별시 금천구 가산디지털1로 181, 가산더블유센터 1508호 COPYRIGHT ⓒ ALL RIGHT RESERVED.