웹 환경에서 파일을 업로드 하는 경우에 해당 파일유효성 검증을 따로 하지 않는 경우, 악성콘텐츠가 삽입된 페이지에 접속한 사용자는 악성코드 유포 사이트가 자동으로 호출되어 악성코드에 감염될 수 있는 취약점을 의미 합니다.
악성콘텐츠는 SQL 인젝션, Cross Site Scripting, 파일 업로드를 통한 페이지 위변조 기법 등을 통해 삽입이 가능하면서 서버 내부의 자원 탈취 및 변조, 클라이언트 브라우저에게의 악성코드 삽입 등이 가능하므로 해당 취약점은 반드시 조치가 되어야 합니다.
#방법1
취약점에 대한 첫번째 조치로는 브라우저에서 허용된 파일 확장자만 업로드 할 수 있도록 제한을 두는 것 입니다.
일반적으로 file테그에 change옵션을 통하여 파일 확장자를 제한 합니다.
아래 코드는 간단하게 Jquery로 구현된 input type file 테그에 대한 제한을 주는 코드 입니다.
$('#파일테그').change(function(){
const files = $(this)[0].files
const fileType = files[0]['type']
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/jpg']
if (!validImageTypes.includes(fileType)) {
alert('이미지만 등록 가능 합니다.')
$(this).val(null)
return
}
})
브라우저에서의 파일 확장자 확인만으로도 기본적인 보안조치를 할 수 있습니다.
그러므로 파일 제한에 대한 기능은 1차로 브라우저에서 하는 것을 잊지 말아야 합니다.
#방법2
그러나 이러한 브라우저의 유효성 검증을 우회하여 파일을 업로드 할 수 있으므로 결과적으로는 파일을 받는 서버에서의 파일 확장자 체크가 필수 입니다.
확장자를 위변조한 파일에 대비하여 파일 자체가 지니고 있는 Mime타입을 확인 해 준다면 훨씬 더 강력한 검증이 이루어 질 수 있겠습니다.
아래 코드는 Java에서 파일 확장자를 확인하기 위한 샘플 클래스 입니다.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.tika.Tika; //아파치 Tika 라이브러리 입니다(Maven에서 받을 수 있습니다)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
/****
* 파일 유효성을 담당하는 비지니스 성격의 클래스 입니다. <br>
* FileValidator 메소드와 removeSystemTmpFile 메소드를 지원합니다.
* */
public interface FileValidator {
public static final Logger logg = LoggerFactory.getLogger(FileValidator.class);
//허용되는 파일 확장자 모음 입니다.
public static final String[] OK_FILE_TYPE = {".txt",".csv",".xls",".xlsx",".hwp",".png",".jpg",".jpeg",".gif",".pdf",".zip",".xml",".html",".7z", ".rar", ".alz", ".tar", ".tgz", ".gz", ".enc"};
public static final String[] MIME_TYPE = {"javascript","json","msword","pdf","excel","powerpoint","spreadsheetml","wordprocessingml","sheet","document","xml","zip","image","audio","mpeg","text","outlook","works","compressed","compress","haansofthwp","hancom","haansofthml", "haansofthwt"};
/***
* 파일 유효성을 검사하는 메소드 입니다. <br>
* 위 확장자에 포함되지 않으면 멀티파트 객체의 파일을 전부 제거 합니다.<br>
* 반환은 논리값 입니다.
* **/
default public boolean Validator(MultipartFile[] attachFiles) {
if(attachFiles == null || attachFiles.length == 0) return true;
Tika tika = new Tika();
boolean isInsertOk = true;
for(MultipartFile attachFile : attachFiles) {
boolean result = false;
String nuls = attachFile.getOriginalFilename();
//#1. 확장자로 금지파일 항목을 조사 합니다.
if(!nuls.equals("")) { //첨부파일이 존재한 경우 입니다.
String ext = nuls.substring(nuls.lastIndexOf("."), nuls.length()).toLowerCase();
for(String CK : OK_FILE_TYPE){
if(ext.equals(CK)){
result = true;
break;
}
}
} else { //첨부파일에 아무것도 없는 빈 객체로 들어온 경우를 의미 합니다.
result = true;
break;
}
if(!result) { //금지된 파일이 온 경우라면,
removeSystemTmpFile(attachFile);
isInsertOk = false;
}
result = false;
//#2. 마임타입으로 한번 더 파일을 조사 합니다.
try {
String detectedType = tika.detect(attachFile.getBytes());
if(detectedType != null) detectedType = detectedType.toLowerCase();
for(String check : MIME_TYPE){
if(detectedType.indexOf(check) > -1){
result = true;
break;
}
}
} catch (IOException e) {
logg.error("file detect failed ",e);
}
if(!result) { //금지된 파일이 온 경우라면,
removeSystemTmpFile(attachFile);
isInsertOk = false;
}
}
if(!isInsertOk) { //반복문을 통해서 금지된 파일로 걸린적이 있다면 파일 전부를 소거해버립니다. 뭘 담았을지 모르니까요.
for(MultipartFile attachFile : attachFiles) {
removeSystemTmpFile(attachFile);
}
}
return isInsertOk;
}
/**
* 멀티파트로 넘어온 스트림을 파일로 변환한 뒤에 해당 파일을 제거 해 줍니다.
* **/
default public void removeSystemTmpFile(MultipartFile targetFile){
File convFile = new File(targetFile.getOriginalFilename());
FileOutputStream fos = null;
try {
fos = new FileOutputStream(convFile);
fos.write(targetFile.getBytes());
} catch (IOException e) {
} finally {
try { if(fos != null) fos.close();
} catch (IOException e) { ; }
}
if(convFile.isFile()){
convFile.delete();
convFile = null;
}
}
}
이상으로 표준취약점중 1가지인 악성 콘텐츠(CS)에 대해서 간단하게 살펴보았습니다.
궁금한점 또는 틀린 부분은 언제든 연락주세요! 👻
'웹 취약점(Web vulnerability)' 카테고리의 다른 글
12. 불충분한 인증(IA) (0) | 2021.12.02 |
---|---|
11. 크로스 사이트 스크립팅(XS, XSS, Cross Site Scripting) (0) | 2021.12.02 |
9. 정보 누출(Information Leakage) (0) | 2021.11.29 |
8. 디렉토리 인덱싱(directory indexing) (0) | 2021.11.29 |
7. Xpath 인젝션(XML Path Language) (0) | 2021.11.29 |
댓글