-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
관련 이슈
- Related to 링크 생성 시 OG 이미지 S3 업로드 및 저장소 구축 #163
이슈 배경
현재 링크 생성 API(POST /v1/links)는 클라이언트로부터 imageUrl을 전달받아 서버가 해당 리소스를 다운로드 및 업로드 진행
하지만 이 구조는 클라이언트가 임의의 URL(예: 내부망 IP, 로컬 파일 경로 등)을 전송할 경우, 서버가 이를 검증 없이 요청하는 SSRF 공격에 노출될 위험이 존재함
개선 방향
보안 강화를 위해 이미지 업로드 시점을 앞당기고, 링크 생성 시에는 검증된 리소스만 사용하도록 로직을 변경합니다.
-
AS-IS:
scrapeMetadata: OG 태그 정보(원본 이미지 URL)만 반환.createLink: 클라이언트가 준 URL을 믿고 다운로드 시도 (🚨 Risk) -> S3 업로드.
-
TO-BE (캐싱 전략):
scrapeMetadata: OG 태그 수집 시점에 S3로 이미지를 업로드(캐싱) 하고, 클라이언트에게는 S3 URL을 반환.createLink: 클라이언트가originalUrl을 주면, 서버가 Deterministic UUID(URL 기반 고유 키) 로직을 통해 S3에 이미 해당 파일이 존재하는지 확인하고, 존재할 경우 다운로드 없이 매핑만 수행.
1. OG 조회 로직 개선 (LinkFacade.scrapeMetadata)
- 기능 변경: 단순히 메타데이터만 파싱 하던 로직에 S3 업로드 과정을 추가함.
- 프로세스:
- URL 크롤링 및 OG 태그 파싱.
ImageUploader를 호출하여 이미지 다운로드 및 S3 업로드 수행.- 이때, Deterministic UUID 전략을 사용하여 고유한 파일명 생성.
- S3 업로드 완료 후, 클라이언트에게는 원본 URL 반환.
2. 링크 생성 로직 개선 (LinkFacade.createLink)
- 기능 변경: 클라이언트가 전달한
imageUrl을 무조건 다운로드하는 로직 제거. - 프로세스:
- 전달받은
imageUrl을 이용해 Deterministic Key 를 다시 생성. s3Template.objectExists(key)를 통해 S3에 해당 파일이 존재하는지 확인하는 Cache Hit Check 과정 진행.- Case 1 (Cache Hit):
scrapeMetadata단계에서 이미 업로드된 파일이 확인됨.- 별도의 다운로드 없이 즉시 S3 URL을 매핑하여 저장. (SSRF 원천 차단 & 성능 최적화)
- Case 2 (Cache Miss):
- 사용자가 크롤링 단계를 거치지 않고 직접 API를 호출했거나, 캐싱이 만료된 경우.
- 보안 강화: 즉시 다운로드하지 않고, SSRF 방어 로직(Validator) 을 통과한 URL에 한해서만 업로드 수행.
- 검증 실패 시: 업로드를 수행하지 않고
Default Image사용.
- 전달받은
3. SSRF 방어 로직 구현 (UrlValidator)
- 검증 항목:
- Protocol Check:
http,https스키마만 허용 (file://,ftp://등 차단). - IP Address Check:
InetAddress를 사용하여 호스트가 사설 IP(Private IP) 대역(Loopback, SiteLocal 등)인지 확인하고 차단. - Allowlist: 필요 시 신뢰할 수 있는 도메인인지 확인하는 로직 고려.
- Protocol Check:
기대 효과
- 보안성:
createLink시점에 검증되지 않은 외부 리소스에 대한 접근을 최소화하여 SSRF 방지. - 성능:
scrapeMetadata에서 이미 업로드를 마쳤으므로, 사용자가 저장 버튼을 누르는createLink시점에는 I/O가 발생하지 않아 응답 속도 대폭 향상.