자격/SW보안약점진단원

구현단계 보안약점 제거 기준-위험한 형식 파일 업로드

Ignatius Heo 2023. 7. 4. 03:20

작성일: 230704

 

※ 본 게시글은 학습 목적으로 행정안전부·KISA의 소프트웨어 보안약점 진단 가이드, 소프트웨어 개발보안 가이드를 참고하여 작성하였습니다.

 

정리 내용: 소프트웨어 보안약점 진단 가이드(232~238p)

 

구분 - 입력데이터 검증 및 표현
설계단계 - 업로드·다운로드 파일 검증
https://cryptocurrencyclub.tistory.com/98
개요
서버 측에서 실행될 수 있는 스크립트 파일(asp, jsp, php 파일 등)이 업로드 가능하고, 이 파일을 공격자가 웹으로 직접 실행시킬 수 있는 경우, 시스템 내부명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있는 보안약점이다.

진단 세부사항
(설계단계)

 ① 업로드되어 저장되는 파일의 타입, 크기, 개수, 실행권한을 제한해야 한다. 업로드되는 파일의 타입, 크기, 개수 및 실행권한을 제한하도록 설계하고 있는지 확인한다.
  ㅇ  업로드 가능한 파일의 타입, 크기, 개수와 저장 시 파일의 퍼미션을 정의하고 있는지 확인(업로드 기능을 지원하는 프레임워크, 라이브러리 사용 여부 확인 후 파일 속성 제한 설정 여부 확인)
  ㅇ  허용되지 않는 파일 타입, 크기, 개수 업로드의 제한 기능 테스트 계획 수립 여부 확인
  ㅇ  업로드 후 서버에 저장된 파일의 실행 제한 여부 점검 테스트 계획 수립 여부 확인
 
 ② 업로드되어 저장되는 파일은 외부에서 식별되지 않아야 한다. 업로드된 파일을 외부에서 식별되거나 직접 접근할 수 없도록 설계하고 있는지 확인한다.
  ㅇ  저장 경로와 파일명을 외부에서 알 수 없도록 정의하는지 확인(난수 + 중복 안되도록)
  ㅇ  원본 파일명과 저장경로/파일명의 매핑정보를 관리하도록 설계되어 있는지 확인
  ㅇ  저장된 파일명, 경로가 외부에서 식별 가능한지 점검할 수 있는 테스트 계획 수립 여부 확인
 
 ③ 파일 다운로드 요청 시, 요청파일명에 대한 검증작업을 수행해야 한다. 파일 다운로드 요청 시 파일에 대한 검증작업이 이루어지도록 설계하고 있는지 확인한다.
  ㅇ  파일 다운로드 요청방식의 안전한 설계 여부 확인(경로 조작 문자 포함 여부, DB정보를 이용하여 요청파일의 유효성 점검 여부)
  ㅇ  조작된 파일명을 이용한 파일 다운로드 요청의 차단 여부 확인
 
 ④ 다운로드받은 소스코드나 실행파일은 무결성 검사를 실행해야 한다. 다운로드받은 소스코드와 실행파일에 대해 무결성을 검증하도록 설계하고 있는지 확인한다.
  ㅇ  파일의 무결성 검사를 위한 값(예: 해시)의 제공 여부 확인
  ㅇ  무결성 검사 수행 후 파일 다운로드하도록 절차가 설계되어 있는지 확인
  ㅇ  변조된 파일에 대한 다운로드 처리가 차단되는지 점검할 수 있는 테스트 계획의 수립 여부 확인

보안대책
(구현단계)

화이트 리스트 방식으로 허용된 확장자만 업로드를 허용한다.

업로드 되는 파일을 저장할 때에는 파일명과 확장자를 외부사용자가 추측할 수 없는 문자열로 변경하여 저장하며, 저장 경로는 ‘web document root’ 밖에 위치시켜서 공격자의 웹으로 직접 접근을 차단한다.

또한 파일 실행여부를 설정할 수 있는 경우, 실행 속성을 제거한다.

진단방법
(구현단계)

① 외부 입력값에서 파일명을 얻어오는 부분이 존재하는지 확인하고

② 허용된 확장자에 대해서만 파일 업로드를 허용하는지 확인한다. 제어문 등을 사용하여 허용된 파일만 업로드 될 경우와 업로드된 파일명을 외부에서 알 수 없는 형태로 변경할 경우엔 안전하지만 그 외에는 취약하다.

 

 

다. 코드예제


ㅇ 분석

1: MultipartRequest multi
= new MultipartRequest(request,savePath,sizeLimit,"euc-kr",new DefaultFileRenamePolicy());
2: ......
3:
4: String fileName = multi.getFilesystemName("filename");
5: ......
6: sql = " INSERT INTO board(email,r_num,w_date,pwd,content,re_step,re_num,filename)
"+ " values ( ?, 0, sysdate(), ?, ?, ?, ?, ? ) ";
7: PreparedStatement pstmt = con.prepareStatement(sql);
8: pstmt.setString(1, stemail);
9: pstmt.setString(2, stpwd);
10: pstmt.setString(3, stcontent);
11: pstmt.setString(4, stre_step);
12: pstmt.setString(5, stre_num);
13: pstmt.setString(6, fileName);
14: pstmt.executeUpdate();
15: Thumbnail.create(savePath+"/"+fileName, savePath+"/"+"s_"+fileName, 150);

ㅇ 설명

1. r4에서 저장할 파일 이름은 잘 받고, r6에서도 쿼리문 잘 만들어놨는데 파일 저장하는 과정 전에 파일을 검증하는 부분이 없음. 썸네일이 붙은걸 보니 이미지 확장자를 업로드해야 하나봄

 

ㅇ 수정

1: MultipartRequest multi
= new MultipartRequest(request,savePath,sizeLimit,"euc-kr",new DefaultFileRenamePolicy());
2: ......
3: String fileName = multi.getFilesystemName("filename");
4: if (fileName != null) {
5: 
6: String fileExt = FileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
7: 
8: if (!"gif".equals(fileExt) && !"jpg".equals(fileExt) && !"png".equals(fileExt)) {
9: alertMessage("업로드 불가능한 파일입니다.");
10: return;
11: }
12: }
13: ......
14: sql = " INSERT INTO board(email,r_num,w_date,pwd,content,re_step,re_num,filename)
“ + " values ( ?, 0, sysdate(), ?, ?, ?, ?, ? ) ";
15: PreparedStatement pstmt = con.prepareStatement(sql);
16: ......
17: Thumbnail.create(savePath+"/"+fileName, savePath+"/"+"s_"+fileName, 150);

ㅇ 설명

1. r8에서처럼 업로드 허용 확장자 화이트리스트를 제작.

 


ㅇ 분석

1: string fn = Path.GetFileName(FileUploadCtr.FileName);
2: //
3: FileUploadCtr.SaveAs(fn);
4: StatusLabel.Text = "Upload status: File uploaed!";

ㅇ 설명

1. 마찬가지로 파일에 대한 검증이 없음

 

ㅇ 수정

1: //
2: if (FileUploadCtr.PostedFile.ContentType == "image/jpeg")
3: {
4: if (FileUploadCtr.PostedFile.ContentLength < 102400)
5: {
6: string fn = Path.GetFileName(FileUploadCtr.FileName);
7: FileUploadCtr.SaveAs(Server.MapPath("~/") + fn);
8: StatusLabel.Text = "Upload status: File uploaed!";
9: }
10: else
11: StatusLabel.Text = "Upload Status: The File has to be less than 100 kb!";
12: }
13: else
14: StatusLabel.Text = "Upload Status: Only JPEG files are accepted!";

ㅇ 설명

1. r2에서 파일형식은 jpeg로 제한함

2. r4에서 파일 크기는 100KB로 제한함

 

 

 

 

 

끝.