Spring 의 multipart file upload 를 위한 인터페이스
Apache Tomcat은 Jakarta Servlet 사양에 정의된 파일 업로드 기능을 제공하기 위해
Apache Commons FileUpload 의 이름이 변경된 패키지 복사본을 사용한다.
상단과 같이 톰캣을 사용할 경우(외장톰캣 또는 Spring Boot 내장 톰캣) StandardServletMultipartResolver 를 사용하면 CommonsMultipartResolver 를 사용한것과 유사하게 Part Api 를 통한 파일 처리시 컨테이너단에서 Apache Commons FileUpload 의 이름이 변경된 패키지 복사본을 사용해 파일을 처리한다.
Tomcat 을 사용한다면 CommonsMultipartResolver 를 사용할 필요가 없다.
단, 배포환경에서 톰캣 버전이 달라지는 경우라면 CommonsMultipartResolver 를 사용할만 하다.
Apache Commons FileUpload에서 발생하는 서비스 거부 취약점
으로서 1.5 버전 이전엔
multipart form 처리시 파일의 수 제한을 두지 않았기 때문에 Dos 공격 가능성이 있는 취약점이다.
제품명 | 영향받는 버전 | 해결 버전 |
---|---|---|
Apache Commons FileUpload | 1.0-beta-1 ~ 1.4 | 1.5 |
Apache Tomcat | 11.0.0-M1 | 11.0.0-M3 |
Apache Tomcat | 10.1.0-M1~ 10.1.4 | 10.1.5 |
Apache Tomcat | 9.0.0-M1~ 9.0.70 | 9.0.71 |
Apache Tomcat | 8.5.0~ 8.5.84 | 8.5.85 |
KISA 보안공지에 따르면 라이브러리 버전 업그레이드만 하면 되는것으로 보이지만
실제 별도 세팅이 필요하며 하단 사항을 공식 도큐먼트에서 확인할 수 있다.
the new configuration option (FileUploadBase#setFileCountMax) is not enabled by default and must be explicitly configured.
커밋 확인시 하단과 같이 fileCountMax 값을 세팅하였다.
upload.setFileCountMax(maxParameterCount - parameters.size());
fileCountMax 값은 Connector 의 maxParameterCount(default 10,000) - 처리된 파라미터 수
365 ~ 368 라인을 보면 전달된 form item 개수와 지정된 fileCountMax 값을 비교하는 코드가 추가되었다.
multipart/form-data 형식에서 Request 로 부터 추출한 FileItem 은 File 형식만 포함하지 않으며
Form 에 전송된 파라미터 모두를 포함한다.
multipart 요청시 파일 3개 form item 10개의 경우 FileItem 13개로 처리된다.
하단 인터페이스 주석에서 확인 가능.
public interface FileItem extends FileItemHeadersSupport
This class represents a file or form item that was received within a multipart/form-data POST request.
Apache Commons FileUpload 버전을 올리더라도 CommonsMultipartResolver 의 경우
spring-web 의 코드이므로 headerEncoding 설정을 하지않는다면 fileCountMax 를 세팅하는
부분이 존재하지 않아 별도로 Override 를 해야한다.
public class CommonsMultipartResolverCustom extends CommonsMultipartResolver {
@Override
protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
FileUpload fileUpload = super.newFileUpload(fileItemFactory);
fileUpload.setFileSizeMax(1_073_741_824); // 100MB
fileUpload.setFileCountMax(10_000);
return fileUpload;
}
}
@Bean
public CommonsMultipartResolverCustom multipartResolver() {
return new CommonsMultipartResolverCustom();
}
만약 headerEncoding 설정까지 추가한다면 Override 없이 하단과 같이 세팅도 가능하다.
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setDefaultEncoding("UTF-8");
multipartResolver.setMaxUploadSize(1_073_741_824); // 100MB
multipartResolver.getFileUpload().setFileCountMax(10_000);
return multipartResolver;
}
톰캣을 사용한다면 보안취약점이 패치가 적용된 톰캣 버전을 사용하면 된다.
만약 톰캣버전을 변경할 수 없는 경우라면 Apache Commons FileUpload 1.5
의존성 추가후 CommonsMultipartResolver 를 사용하도록 변경하면 된다.