1. 정의
위험한 형식 파일 업로드 (Unrestricted Upload of File with Dangerous Type)
서버측에서 실행될 수 있는 스크립트 파일(asp, jsp, php 파일 등)이 업로드 가능하고, 이 파일을 공격자가 웹을 통해 직접 실행시킬 수 있는 경우 공격자는 스크립트 파일을 업로드하고 이 파일을 통해 시스템 내부명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있다.
2. 해결방법
- 업로드하는 파일 타입과 크기를 제한하고, 업로드 디렉터리를 웹서버의 다큐멘트 외부에 설정한다.
- 화이트리스트 방식으로 허용된 확장자만 업로드되도록 하고, 확장자도 대소문자 구분 없이 처리하도록 한다.
- 공격자의 웹을 통한 직접 접근을 차단한다. 또한 파일 실행 여부를 설정 할 수 있는 경우, 실행 속성을 제거한다.
3. 예제
============================== 안전한 코드의 예 =============================
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
String next = (String) mRequest.getFileNames().next();
MultipartFile file = mRequest.getFile(next);
if ( file == null )
return ;
// 업로드 파일 크기를 제한한다.
int size = file.getSize();
if ( size > MAX_FILE_SIZE ) throw new ServletException("Error");
// MultipartFile로 부터 file을 얻음
String fileName = file.getOriginalFilename().toLowerCase();
// 화이트리스트 방식으로 업로드 파일의 확장자를 체크한다.
if ( fileName != null )
{
if(fileName.endsWith("*.doc") || fileName.endsWith("*.hwp") || fileName.endsWith("*.pdf") || fileName.endsWith("*.xls"))
{
/* file 업로드를 위한 로직 */
}
else throw new ServletExeption("Error");
}
// 업로드 파일의 디렉터리 위치는 다큐멘트 루트의 밖에 위치시킨다.
File uploadDir = new File("/app/webapp/data/upload/notice");
String uploadFilePath = uploadDir.getAbsolutePath()+"/" + fileName;
============================================================================
위의 코드와 같이 업로드 파일의 확장자를 검사하여 어용되지 않은 확장자일 경우 업로드를 제한하고, 저장 시 외부에서 입력된 파일명을 그대로 사용하지 않아야 한다.
또 확장자가 실행 가능한 위험한 파일 타입인 EXECUTABLE_FILE_TYPE에 해당하는 경우 업로드를 제한하는 방법도 있다.
if(extractFileType(file) == EXECUTABLE_FILE_TYPE)
'04. 시큐어코딩' 카테고리의 다른 글
시큐어코딩(7) - XQuery injection (0) | 2017.11.16 |
---|---|
시큐어코딩(6) - Open Redirect (0) | 2017.11.15 |
시큐어코딩(4) - OS Command Injection (0) | 2017.11.15 |
시큐어코딩(3) - Cross-site Scripting (0) | 2017.11.14 |
시큐어코딩(2) - Resource Injection (0) | 2017.11.14 |