Skip to content

검토 요청: /storage/{path} Generic Signed Upload Endpoint 노출 #52

Description

@glitter-gim

요약

Production 환경의 엔드포인트 노출 상태를 점검하던 중 Laravel Filesystem 기능이 자동 등록하는 다음 업로드 엔드포인트를 확인했습니다.

PUT /storage/{path}

조사 결과 해당 엔드포인트는 Laravel 내부의 Signed URL 검증을 사용하고 있어 즉시 악용 가능한 공개 업로드 취약점으로 보이지는 않았습니다.

다만 애플리케이션 관점에서는 특정 리소스에 종속되지 않은 Filesystem 업로드 엔드포인트로 동작하며, 현재 프로젝트에서 실제 사용 중인지와 현재 구성이 의도된 것인지 확인이 필요해 보여 이슈를 등록합니다.


확인된 내용

1. 라우트 등록 위치

프로젝트 라우트 파일이 아니라 Laravel Framework에서 자동 등록됩니다.

vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemServiceProvider.php

실제 등록된 라우트:

GET|HEAD storage/{path}
PUT      storage/{path}

라우트 분석 결과:

middleware = []
path regex = .*

route:list 기준으로는 애플리케이션 레벨 인증·권한 미들웨어가 보이지 않았으며,
실제 접근 제어는 Laravel Filesystem 내부의 Signed URL 검증 로직에서 수행되는 것으로 확인했습니다.


2. 인증/인가 방식

PUT 요청은 다음 조건을 만족해야만 허용됩니다.

$request->boolean('upload')
&& $request->hasValidRelativeSignature()

따라서 현재 상태는 무인증 임의 업로드가 아닌 것으로 확인했습니다.

유효한 Signed URL이 반드시 필요합니다.


3. Filesystem Disk 구성

현재 다음 Disk들이 모두 serve => true 상태입니다.

local
modules
plugins

라우트 분석 결과 세 Disk 모두 동일한 URL 패턴인

/storage/{path}

를 사용하며, 실제 route:list에서는 최종적으로 다음 라우트만 노출되는 것을 확인했습니다.

storage.plugins
storage.plugins.upload

이 부분이 의도된 동작인지 궁금합니다.


4. 파일 쓰기 동작

Signed URL 검증을 통과하면 내부적으로 다음 코드가 수행됩니다.

Storage::disk(...)->put($path, $request->getContent());

관찰된 특징은 다음과 같습니다.

  • overwrite 허용
  • nested path 허용

조사 범위 내에서는 이 Endpoint를 사용하는 애플리케이션 레벨 기능이나
Signed Upload URL 발급 경로를 확인하지 못했습니다.

따라서 현재 프로젝트에서 실제 사용 중인 기능이 존재하는지 궁금합니다.

Flysystem이 디스크 루트 밖으로 벗어나는 ../ 경로는 차단하는 것을 확인했습니다.

다만 엔드포인트 자체는 특정 리소스에 종속된 업로드 API가 아니라
Filesystem 레벨의 업로드 Endpoint 형태로 동작하는 것을 확인했습니다.


5. 사용처 조사

프로젝트 코드에서 다음 키워드를 검색했습니다.

temporaryUploadUrl
buildTemporaryUploadUrlsUsing

현재 애플리케이션 코드에서는 명확한 사용처를 찾지 못했습니다.

그래서 실제 사용 중인 기능이 존재하는지 궁금합니다.


질문

  1. /storage/{path} Signed Upload Endpoint 노출은 의도된 설계인가요?
  2. 여러 Disk가 동일 /storage/{path} 경로를 사용하는 현재 구조는 의도된 동작인가요?
  3. 현재 이 엔드포인트를 사용하는 기능이 존재하나요?
  4. 사용하지 않는다면 serve => true 제거를 고려할 수 있을까요?
  5. 현재 구조가 의도된 것이라면, 범용 Filesystem Upload Endpoint를 선택한 이유가 있을까요?

결론

현재 분석 결과 즉시 악용 가능한 공개 업로드 취약점은 확인하지 못했습니다.

다만

  • 여러 Disk가 동일 /storage 경로를 공유하는 구조
  • Signed Upload Endpoint의 실제 사용처를 확인하지 못한 점
  • Filesystem Upload Endpoint가 Production 환경에 노출되어 있는 점

은 설계 관점에서 검토 가치가 있다고 판단했습니다.

본 이슈는 취약점 제보가 아니라 현재 구성이 의도된 설계인지 확인을 요청드리는 검토 이슈입니다.

참고로 본 이슈 등록 이후 운영 중인 환경에서는 해당 Endpoint의 실제 사용처를 확인하지 못하여 filesystem serving을 비활성화하였으며, /storage/{path} Endpoint를 제거하였습니다.


추가 참고 자료

본 이슈 등록 이후 수행한 추가 조사 및 운영 환경 조치 기록은 아래 문서에 정리하였습니다.

https://hub.glitter.kr/board/resources/61

이 문서는 본 이슈의 결론을 변경하기 위한 자료가 아니라, 이슈 등록 이후 수행한 추가 조사와 운영 환경 대응 내용을 기록한 참고 자료입니다.

해당 기록에는 다음 내용이 포함되어 있습니다.

  • /storage/{path} Endpoint 동작 분석
  • Signed URL 검증 방식 확인
  • 실제 사용처 조사
  • local · modules · plugins 의 serve=true 구성 검토
  • 운영 환경에서 수행한 구성 변경 및 검증 결과
  • 주요 API 및 화면 영향 검증 결과

본 이슈는 설계 의도 확인을 위한 검토 요청이며, 위 문서는 조사 및 운영 대응 과정을 기록한 참고 자료입니다.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions