반응형
1. 위험한 형식 파일 업로드 정의
서버측에서 실행될 수 있는 스크립트파일(asp, jsp, php 파일 등)이 업로드 가능하고, 이 파일을 공격자가 웹을 통해 직접 실행 시킬 수 있는 경우 공격자는 스크립트 파일을 업로드하고, 이 파일을 통해 시스템 내부 명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있다.
예를들어 다음과 같은 게시판에 악성 파일을 업로드하고 서버내에서 실행시키면 서버에 영향을 줄 수 있다.
2. 안전한 코딩기법
- 업로드하는 파일 타입과 크기를 제한하고, 업로드 디렉터리를 웹서버와 분리하여 설정한다.
- 허용된 확장자만 업로드되도록하고, 확장자도 대소문자 구분 없이 처리하도록 한다.
- 공격자의 웹을 통한 직접 접근을 차단한다. 또한 파일 실행 여부를 설정할 수 있는 경우, 실행 속성을 제거한다.
3. 예시
사용자가 업로드하는 파일의 유효성을 검사하지 않으면, 위험한 유형의 파일을 공격자가 업로드하거나 전송할 수 있다.
public void upload(HttpServletRequest request) throws ServletException {
MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request;
String next = (String) mrequest.getFileNames().next();
MultipartFile file = mrequest.getFile(next);
// MultipartFile로부터 file을 얻음
String filename = file.getOriginalFilename();
// upload 파일에 대한 확장자 체크하지 않음
File uploadDir = new File("/app/webapp/data/upload/notice");
String uploadFilePath = uploadDir.getAbsolutePath()+"/" + fileName;
}
다음은 업로드 파일의 크기를 제한하고, doc, hwp, pdf, xls 확장자만 저장을 허용하며, 업로드 파일의 디렉터리 위치를 다큐먼트 루트의 밖에 위치시키는 방법이다.
public void upload(HttpServletRequest request) throws ServletException {
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("에러");
// MultipartFile로 부터 file을 얻음
String fileName = file.getOriginalFilename().toLowerCase();
// 업로드 파일의 확장자를 체크한다.
if(fileName != null)
{
if(fileName.endsWith(".doc") || fileName.endsWith(".hwp")
|| fileName.endsWith(".pdf") || fileName.endsWith(".wls"))
{
파일업로드함
}
else throw new ServletException("에러");
}
//업로드 파일의 디렉터리 위치는 다큐먼트 루트의 밖에 위치시킨다.
File uploadDir = new File("/app/webapp/data/upload/notice");
String uploadFilePath = uploadDir.getAbsolutePath()+"/" + fileName;
}
4. 추가적인방법
- 웹 서버 내부 디렉토리에 실행권한을 주지 않는다. 즉 서버 내부에 파일을 실행할 수 없게하여 공격으로부터 대비한다
- 파일이름 및 확장자를 암호화(난수화) 하여 저장한다. DB에 암호화된 파일명, 원래의 파일명, 파일크기, 확장자 등 정보를 저장한다면 사용자에게 원래의 파일명으로 화면에 뿌려주되 파일명은 암호회되어있어서 사용자는 직접적으로 접근할 수 없다. DB에 원래 파일명을 적어놓으므로 복호화 과정이 필요없어서 해쉬를 사용해도 괜찮을 것 같음(추측)
반응형
'프로그래밍 > 시큐어코딩' 카테고리의 다른 글
[시큐어 코딩] #7 크로스사이트 요청 위조 / CSRF (0) | 2020.07.02 |
---|---|
[시큐어 코딩] #6 신뢰되지 않는 URL 주소로 자동 연결 (0) | 2020.07.02 |
[JAVA] Enum이란? (0) | 2020.07.02 |
[시큐어 코딩] #4 운영체제 명령어 삽입 (0) | 2020.07.02 |
[시큐어 코딩] #3 크로스 사이트 스크립트 / XSS (0) | 2020.07.01 |