티스토리 뷰
웹해킹을 진행하면 가장 먼저 소개하는 취약점이 XSS인 것 같습니다.
XSS는 기본적으로 입력값과 출력값을 검증하지 않아서 악성코드가 삽입되거나, 인증정보가 탈취되는 취약점이죠.
그 과정이 어떻게 되느냐에 따라 Stored인지 Reflected인지 등으로 구분이 되는 것일 뿐 개인적으로 크게 중요하지는 않아 보입니다. 오히려 중요한 점은 개발자가 검증하는 값이 사용자로부터 직접 입력받는 값에 대해서만 검증한다는 점일 것 같습니다. 입력값이 사용자 기준이 아니라 웹서버 기준으로 입력되는 모든 데이터를 검증하는 것이 가장 중요하기 때문이죠.
이와 관련된 일부 케이스는 아래와 같습니다.
01. 일반적인 파라미터를 통해 전달받은 입력값의 검증
02. 일부 입력값의 검증 예외처리
03. 일부 입력값을 가져오는 함수에 대한 검증 미적용
04. 파일 업로드를 통한 입력값 전달 시 파일 내 데이터 검증
05. 멀티파트에 대한 입력값 검증
06. RequestBody / ResponseBody 를 통해 전달되는 입력값의 검증
07. 필터링 된 입력값을 출력 시 재치환
이 밖에도 미쳐 발견하지 못한 다양한 케이스가 있을 수 있습니다.
01. 일반적인 파라미터를 통해 전달받은 입력값의 검증
웹 개발을 하게 되면, 페이지에서 다른 페이지로 값을 전달하거나 저장 및 출력을 할 때 데이터를 전달을 하게 된다.
대체로 request객체를 통해 데이터가 전달이 되는데, 개발언어별로 필터링 방식에 차이는 있지만 이 request 객체를 통해 전달받은 값을 검증해줘야 합니다.
필터링은 XSS를 유발할 수 있는 특수기호( <, >, (, ), ', ", #, & 등 )의 포함여부를 검증하거나, 특수기호를 입력해야 하는 특수한 경우에는, XSS를 통해 발생할 수 있는 위험한 키워드 등을 대/소문자 구분없이 필터링해주면 될 것 같습니다.
이 부분은 OWASP의 XSS Cheat Sheet를 이용하거나 각 언어 별 보안모듈을 통해 필터링하는 것도 방법입니다.
단, 보안모듈에서 지원하는 방식이라도 우회방법은 존재할 수 있으므로 잘 파악해서 사용되어야 하죠.
ex. Lucy 필터링 우회
=> Lucy의 티폴트 필터링의 경우 (, ) 를 필터링하지 않고 있기 때문에, 특정한 상황에서 XSS가 발생이 가능하다.
<script>
var temp=<%=request.getParameter("param");%>;
...
</script>
02. 일부 입력값에 대한 검증 예외처리
선처리 필터링이 어려운 초기 개발언어를 제외하면 최근 개발언어들은 모두 선처리 필터링이 가능합니다.
물론 Classic ASP나 PHP도 단일 파일로 필터링 함수를 만들고 모든 페이지에서 include를 통해 선처리가 되는 것 처럼 만들어 줄 수는 있습니다.
어째뜬 대체로 선처리 필터링을 구현하는데, 서비스 제공을 위해 특정 시점의 특정 입력값에 대해서는 필터링을 미흡하게 하거나 적용을 할 수 없는 경우가 있습니다. 대체로 쇼핑몰 등에서 판매자들이 자신들의 상품을 더욱 잘 팔기위해 HTML 코드 자체를 입력값으로 전달받는 경우가 그러한데, 사실 보안만 생각한다면 당연히 HTML코드를 입력값으로 전달하면 안되겠죠.
하지만 서비스 제공업체는 자신들의 수익을 위해 HTML 코드를 입력받고 해당 코드가 정상적으로 출력이 되는 프로세스에서 무조건 특수기호를 필터링해서 스크립트가 실행되지 않도록 하는 것에 어려움이 발생하게 됩니다. 때문에 개발자는 이런 경우 아예 필터링을 하지 않는 상황이 생기게 되는 것이죠.
때문에 이런 경우는 HTML코드를 입력받아야만 하는 페이지 한정으로 특수기호 대신 키워드 방식의 필터링을 하도록 로직을 구성해야 합니다. 이때 인터뷰 등을 통해 허용되는 키워드를 최소화 시킬 수 있도록 해야 하며, 키워드 필터링을 수행할 때는 대/소문자를 구분하지 않도록 해야 합니다.
03. 일부 입력값을 가져오는 함수에 대한 검증 미적용
대부분의 웹개발 언어는 다양한 방식으로 파라미터 등으로 전달받는 데이터를 가져올 수 있으며, 전달하는 모든 방법에 대해서 입력값을 검증을 수행해야 합니다.
Java의 경우만 봐도 getParameter, getParameterValues, getParameterMap 등이 존재하는데, 서블릿 선처리를 구현하는 과정에서 getParameter 함수만 필터가 적용되도록 재정의하는 경우가 생각보다 많이 발생합니다. 이후에 모든 페이지에서 getParameter만 사용한다면 문제가 되지 않을 수도 있지만, 다른 방식으로 값을 가져오는 페이지가 존재하거나, 향후 유지보수 과정에서 추가될 경우 특정 함수로 전달되는 입력값에 대해서는 검증없이 사용하게 됩니다.
04. 파일 업로드를 통한 입력값 전달 시 파일 데이터 검증
일부 관리적 목적의 서비스를 구현하는 과정에서 수많은 데이터를 입력하기 힘들기 때문에 엑셀이나 워드 파일을 업로드하여 소스코드에서 파싱 후 데이터를 처리하는 경우가 종종 있습니다.
이런 경우, 선처리 필터링 함수를 통해 입력값을 검증하지 않기 때문에 파일 내 데이터를 별도로 검증을 수행해줘야 합니다. 특히 엑셀파일로 데이터를 업로드 하는 경우, 데이터베이스에 저장될 확률이 매우 크므로 더욱 신경써야 할 것 같습니다.
예전에 어떤 분께서, 사용자로부터 전달받은 데이터의 원본은 훼손하지 않고 DB에 저장한 뒤 출력 시에 필터링을 하는 것이 옳다라고 이야기 해주신 적이 있습니다. 사실 이때 원본 데이터의 훼손에 대해 고민해본 적이 없었기 때문에 꽤 이로운 시간이였지만 현재 웹서비스에서는 출력단 검증을 하더라도, 동일 DB를 함께 사용하는 다른 웹서비스에서 출력단 검증을 하지 않는 경우는 어떻게 될까? 역시 고민이 필요한 부분입니다.
05. 멀티파트에 대한 입력값 검증
게시판을 만들 때 게시글의 전달을 모두 GET 또는 POST 방식으로 전달할 수도 있지만, 첨부파일도 함께 전달하는 경우, 멀티파트를 통해 전달도 가능합니다. 물론 첨부파일만 멀티파트로 전달하고 나머지 데이터는 POST 등으로 2번에 걸쳐 전달하는 경우도 존재하죠.
하지만 선처리 함수는 GET과 POST방식으로 전달되는 입력값만 검증을 수행할 뿐이라 멀티파트 형식으로 전달되는 경우는 검증을 수행하지 않습니다. 때문에 멀티파트로 값을 전달하는 페이지가 있는 경우는 별도의 설정을 통해 멀티파트로 전달받는 값도 검증을 수행해야 합니다.
만약 파일만 멀티파트로 업로드 하는 경우라도, 파일명 등은 함께 전달되기 때문에, 파일명이 저장 및 출력되는지 여부를 검증해봐야 하기 때문에 이런 경우라도 간과해서는 안될 것 같습니다.
06. RequestBody / ResponseBody 를 통해 전달되는 입력값 검증
스프링의 RequestBody / ResponseBody 어노테이션을 통해 입력값을 전달할 수 있는데 이 경우에도 멀티파트 처럼 선처리 필터링을 통해 입력값을 검증하지 않습니다. 때문에 해당 어노테이션을 설정한 컨트롤러에서는 입력값과 출력값에 스크립트로 동작할 수 있는 특수기호와 키워드를 별도로 검증해줘야 합니다.
07. 필터링 된 입력값을 출력 시 재치환
입력값을 필터링할 때 특수기호나 키워드를 화이트 스페이스로 변환하기도 하지만, HTML인코딩된 특정 값으로 변환을 하기도 합니다. 이러한 경우, 사용자가 입력한 값을 스크립트는 동작하지 않고 그대로 보여주기 때문에 좋은 대응방법입니다.
하지만 입력값이 출력이 되는 과정에 대해 개발디자인이 잘못되었거나, 개발자의 실수 또는 어쩔수 없는 경우에 의해 출력 시 안전한 값으로 변환된 값을 재치환 하는 경우가 있습니다. 이러한 경우에는 결국 필터링 없이 입력값을 출력하는 것과 같기 때문에 서블릿 필터링을 통해 입력값을 검증한다고 해서 무조건 안전하다고 생각하면 안됩니다.
Fin
'Web Analytics > Vulnerabilities' 카테고리의 다른 글
인증실패 횟수 관련 분석 (0) | 2019.04.14 |
---|---|
Password 관련 취약점 분석 (0) | 2019.03.09 |
Download 취약점 분석 (0) | 2019.03.06 |
Upload 취약점 분석 (0) | 2019.03.03 |
SQL Injection 취약점 분석 (0) | 2019.03.03 |
- Total
- Today
- Yesterday