본문 바로가기
Java & Spring

멀티파트 업로드: 제한/보안/임시저장 설계

by yamoojin83 2025. 9. 30.

멀티파트 업로드: 제한/보안/임시저장 설계

파일 업로드는 용량 제한, 확장자/시그니처 검사, 임시 저장소 설계가 핵심입니다.

안전한 파이프라인을 만들지 않으면 OOM이나 악성 파일 유입 위험이 있습니다.

설정


spring:
  servlet:
    multipart:
      max-file-size: 20MB
      max-request-size: 25MB
      location: /tmp/upload  # 임시 저장 디렉터리

컨트롤러


@PostMapping(value="/api/upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public UploadResponse upload(@RequestPart("file") MultipartFile file) throws IOException {
  guard(file);
  Path tmp = Files.createTempFile("up-", ".bin");
  file.transferTo(tmp);

  // TODO: 시그니처 검사/바이러스 스캔/이미지 처리
  // ex) Tika로 MIME 판별, Thumbnailator로 썸네일 등

  Path saved = storage.save(tmp, file.getOriginalFilename());
  Files.deleteIfExists(tmp);
  return new UploadResponse(saved.toString());
}

검증(간단 예)


void guard(MultipartFile file) {
  if (file.isEmpty()) throw new IllegalArgumentException("빈 파일");
  if (file.getSize() > 20 * 1024 * 1024) throw new IllegalArgumentException("용량 초과");
  String name = Optional.ofNullable(file.getOriginalFilename()).orElse("");
  if (!name.matches("(?i).+\\.(png|jpg|jpeg|pdf)$")) throw new IllegalArgumentException("허용 확장자 아님");
}

운영 팁

  • 임시 디스크는 별도 파티션/용량 모니터링
  • 신뢰할 수 없는 입력은 Content-Type 대신 매직넘버/시그니처로 판단
  • 대용량은 클라이언트 직업로드(S3 pre-signed URL) + 서버는 메타만 처리

FAQ

Q1. 저장 전에 이미지 크기 알아내기?
A. ImageIO로 스트림에서 메타를 읽어 검증한 뒤 저장.

Q2. 동시 업로드가 많으면?
A. 업로드 전용 스레드풀과 큐 용량을 제한하고, 백프레셔 정책을 명확히 하세요.

 

 

👉 1편: Bean Validation(@Valid)로 입력 검증 표준 만들기

👉 2편: @ControllerAdvice 글로벌 예외 응답(에러코드 규격)

👉 3편: application-{profile}.yml 전략 + 비밀키 분리

👉 4편: Spring Boot Actuator: /health 커스터마이징

👉 5편: @Scheduled 크론 12패턴 + 중복실행 방지

👉 6편: 멀티파트 업로드: 제한/보안/임시저장 설계

👉 7편: Spring Cache로 API 3배 빠르게(@Cacheable/무효화)

👉 8편: Pageable 응답 DTO 규격(정렬·페이지 표준화)