presigned 발급에 contentLength 를 받아 서명에 묶고 5MB 상한 강제 (과도기 선택 필드) - #1053
Merged
Conversation
- Content-Type 은 이미 서명에 묶여 S3 가 강제하지만 Content-Length 는 없어, multipart 시절의 5MB 제한이 S3 직행 PUT 경로에는 걸리지 않았다. 서명은 정확한 값만 받으므로 클라가 발급 요청에 바이트 수를 보내고 서버가 상한을 검사한 뒤 서명에 박는 방식을 택했다 (범위 조건은 presigned POST policy 에만 있어 클라 업로드 방식이 통째로 바뀐다)
- 위시·토너먼트 요청은 contentTypes 목록을 images: [{contentType, contentLength}] 로 교체하고, 프로필은 contentLength 필드를 추가. 두 배열을 인덱스로 맞추는 형태보다 한 장의 정보를 묶는 쪽이 명확하다
- 크기 검증은 상품·프로필 공통이라 형식 정책(ProductImage·ProfileImageFile)과 분리해 UploadSize 값 객체로 두고, 미지정·0 이하(UPLOAD-004)와 상한 초과(UPLOAD-003)를 나눠 클라가 취할 행동이 갈리게 했다
- confirm 이후 크기 검사는 두지 않는다. 서명에 묶인 값과 다른 PUT 은 S3 가 거절하므로 HEAD 로 다시 볼 이유가 없다
- 클라 후속(별도): 발급 요청에 contentLength 를 실어 보내도록 변경
Claude-Session: https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY
|
Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- 직전 커밋은 contentLength 를 필수로 두어 기존 클라 요청이 즉시 400 이 됐다. 구버전 앱을 깨지 않으려면 새 경로(v3)를 파거나 과도기 호환을 두는 두 길이 있었는데, 같은 흐름을 두 벌로 유지하는 비용이 커서 호환 쪽을 택했다 - contentLength 가 없으면 크기 없이 발급한다(서명에 Content-Length 없음). 있으면 종전대로 검증해 서명에 묶는다. UPLOAD-004 는 미지정이 아니라 0 이하에만 붙는다 - 위시·토너먼트 요청은 구버전 contentTypes 목록을 deprecated 로 남겨 images 가 없을 때만 읽는다 - 과도기 코드는 UploadSize.ofOrNull 과 contentTypes 필드 둘이다. 클라 전환이 끝나면 이 둘을 지워 미지정을 400 으로 막는다. 호환 테스트 3건은 그때 400 단언으로 뒤집는다 Claude-Session: https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY
- 코드로 읽히는 설명(서명 동작·검증 흐름 재진술)을 지우고, 과도기 코드의 제거 지점과 선언값을 그대로 서명하는 이유만 남긴다 Claude-Session: https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY
- 과도기 코드 제거 지점과 선언값을 그대로 서명하는 이유, 두 줄만 남긴다 Claude-Session: https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY
- ImageStorage.presignUpload 의 예외 변환 설명과 ImageUploadException 의 도달 경로 설명은 구현·에러 코드로 읽힌다 Claude-Session: https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Situation
spring.servlet.multipart.max-file-size)은 S3 직행 경로에 걸리지 않는다. 서명 유효 시간 안이면 어떤 크기의 객체든 올라갔고, 용량 방어선은 클라 검사뿐이었다.Task
Action
결정 1: 서명에 묶는다
결정 2: 과도기 호환, 이후 필수로 전환
images: [{contentType, contentLength}]를 추가하고, 구버전contentTypes목록은 deprecated 로 남겨images가 없을 때만 읽는다. 프로필은contentLength필드를 추가했다. 두 배열을 인덱스로 맞추는 형태보다 한 장의 정보를 묶는 쪽이 명확하다.contentTypes)ProductImage·ProfileImageFile)과 분리해UploadSize값 객체로 두었다. 미지정을 통과시키는ofOrNull이 과도기 코드이며, 클라 전환이 끝나면 이것만 지우면 미지정이 400 이 된다.S3ImageStorage.presignUpload가 값이 있을 때PutObjectRequest.contentLength를 넣어 서명한다. Content-Type·Content-Length 둘 다 signed header 가 되어 다른 값의 PUT 은 S3 가 403 으로 거절한다.Result
UploadSizeTest가 단위로 담당한다.contentLength를 실어 보낸다. 배포 순서 제약은 없다.contentTypes필드와UploadSize.ofOrNull을 지워 미지정을 400 으로 막는다. 과도기 호환 테스트 3건은 그때 400 단언으로 뒤집는다.연관 이슈
https://claude.ai/code/session_01JmUdSz2GqQ2KWMtR9TJ5tY