Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-38360 — 보안 권고: dash-uploader(Python/PyPI)의 CVE-2026-38360 경로 탐색(CWE-22) | Kitploit
도구/GitHubGitHub/a1ohadance/cve-2026-38360
Vulnerability AnalysisCode AnalysisExploitationWeb SecurityPenetration TestingLearning & Education
GitHuba1ohadance/cve-2026-38360

CVE-2026-38360

보안 권고: dash-uploader(Python/PyPI)의 CVE-2026-38360 경로 탐색(CWE-22)

저장소 보기
224개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-38360: dash-uploader의 경로 탐색(Path Traversal) 취약점

CVE NVD CWE Severity Patch Auth Version PyPI Downloads

Total Downloads
License

인증되지 않은 사용자가 fohrloop/dash-uploader(Python, PyPI)에서 임의의 파일을 쓸 수 있게 하는 경로 탐색 취약점으로, (이에 국한되지 않고) 원격 코드 실행(RCE), 애플리케이션 소스 코드 덮어쓰기, 저장형 XSS, 지속적 백도어 설치로 이어질 수 있습니다.

⚠️ 패치는 제공되지 않으며 앞으로도 제공될 예정이 없습니다

이 저장소는 활성 유지 관리자 없이 2025-07-19에 보관(archived)되었습니다. 공개된 모든 버전(0.1.0부터 0.7.0a2까지)이 영향을 받으며 앞으로도 그 상태로 남을 것입니다. 이 패키지는 여전히 월 약 28,000건의 다운로드를 기록하고 있습니다.

프로덕션 환경에서 dash-uploader를 실행하는 모든 사용자는 스스로 완화 조치를 적용해야 합니다. 권장 수정 방법은 Plotly Dash에 내장된 dcc.Upload 컴포넌트로 마이그레이션하는 것입니다. 전체 옵션은 완화(Mitigation)를 참조하세요.

CVE IDCVE-2026-38360 (NVD)
취약점 유형경로 탐색 (CWE-22)
CVSS 3.19.8 / 치명적 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
제품dash-uploader
영향받는 버전0.1.0부터 0.7.0a2까지 (총 18개 릴리스)
수정 버전없음 (프로젝트는 2025-07-19에 보관됨)
공격 벡터원격, 인증 불필요
발견자Muhammad Fitri Bin Mohd Sultan
배정 기관MITRE, 2026-05-07
관련 CVECVE-2026-38361 (동일 라이브러리의 DoS)

설명

dash_uploader/httprequesthandler.py의 request.form.get()에서 가져온 세 개의 사용자 제어 매개변수가 검증이나 정화(sanitization) 없이 os.path.join()과 os.makedirs()에 직접 전달됩니다:

  1. upload_id (57행 → 161행, BaseHttpRequestHandler.get_temp_root): 대상 디렉터리를 제어합니다. 공격자는 upload_id=../../../../usr/local/lib/python3.10/site-packages를 보내 파일이 Python의 패키지 디렉터리에 기록되게 할 수 있습니다.

  2. resumableFilename (51행 → 108행, BaseHttpRequestHandler._post): 최종 파일명을 제어합니다. 공격자는 정상적인 upload_id가 있어도 파일명을 통해 업로드 디렉터리를 벗어날 수 있습니다.

  3. resumableIdentifier (54행 → 64행, BaseHttpRequestHandler._post): os.makedirs()와 함께 사용되어 임시 디렉터리를 생성합니다. 공격자는 파일시스템 어디에나 임의의 디렉터리를 만들 수 있습니다.

업로드 엔드포인트(기본값 /API/dash-uploader)는 인증을 요구하지 않습니다. v0.5.0에서 추가된 http_request_handler 훅은 post_before()를 통한 요청 전 검사를 허용하지만, 취약한 _post() 메서드는 훅이 반환된 후 모든 매개변수를 request.form에서 직접 읽습니다. 훅은 라이브러리가 매개변수를 처리하기 전에 이를 정화할 수 없습니다. 훅을 통해 인증을 추가한 개발자도 인증된 사용자의 경로 탐색 공격에는 여전히 취약합니다.

취약한 코드

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableFilename = request.form.get("resumableFilename", default="error", type=str)
    resumableIdentifier = request.form.get("resumableIdentifier", default="error", type=str)
    upload_id = request.form.get("upload_id", default="", type=str)
    ...
    temp_root = self.get_temp_root(upload_id)                          # upload_id flows in here
    temp_dir = os.path.join(temp_root, resumableIdentifier)            # raw user input -> os.path.join
    if not os.path.isdir(temp_dir):
        os.makedirs(temp_dir)                                          # raw user input -> os.makedirs

def get_temp_root(self, upload_id):
    return os.path.join(self.upload_folder, upload_id)                 # no sanitization: ../../ escapes upload_folder

세 개의 독립적인 탐색 싱크(sink)는 동일한 근본 원인을 공유합니다. 폼 값이 검증 없이 os.path.join과 os.makedirs에 도달합니다.

공격 벡터

인증되지 않은 원격 공격자는 업로드 엔드포인트에 HTTP POST multipart 요청을 보냅니다. upload_id 폼 매개변수에 경로 탐색 시퀀스(../)를 주입함으로써 공격자는 업로드된 파일의 대상 디렉터리를 제어합니다. 예를 들어 upload_id=../../../../usr/local/lib/python3.10/site-packages를 보내면 Python의 패키지 디렉터리에 파일이 기록되고, 다음 인터프리터 시작 시 .pth 자동 실행을 통해 RCE가 가능해집니다.

인증, 세션 토큰, CSRF 토큰이 필요하지 않습니다. 추가 매개변수 두 개(resumableFilename, resumableIdentifier)는 동일한 엔드포인트를 통해 독립적인 경로 탐색 벡터를 제공합니다. 공식 퀵스타트 문서에 나와 있는 기본 라이브러리 구성은 단일 curl 명령으로 악용될 수 있습니다.

영향

서버 프로세스가 쓸 수 있는 모든 디렉터리에 임의의 파일을 쓸 수 있습니다. 이는 다음과 같은 잘 알려진 프리미티브를 통해 **원격 코드 실행(RCE)**으로 이어집니다:

RCE 프리미티브

  • Python .pth 파일을 site-packages에 넣습니다. 다음 인터프리터 시작 시 공격자가 제공한 코드를 실행합니다.
  • sitecustomize.py 또는 usercustomize.py 주입. 모든 Python 시작 시 실행됩니다.
  • 애플리케이션 패키지 디렉터리의 import 가능한 Python 모듈 덮어쓰기. 다음 import 또는 워커 재활용 시 실행됩니다.
  • WSGI/ASGI 엔트리 포인트(예: app.wsgi, wsgi.py) 덮어쓰기. 다음 워커 리로드 시 실행됩니다.
  • 프로세스에 필요한 권한이 있는 경우 Cron 드롭인(/etc/cron.d/, /etc/cron.hourly/, 사용자 crontab 스풀). 예약 실행됩니다.
  • Systemd 유닛 또는 사용자 유닛 드롭인(/etc/systemd/system/, ~/.config/systemd/user/). 다음 서비스 시작 또는 재부팅 시 실행됩니다.
  • 프로세스가 root로 실행될 때 /etc/ld.so.preload 주입. 이후 모든 바이너리 실행에 공격자 코드를 프리로드합니다.
  • 셸 시작 파일 덮어쓰기(~/.bashrc, ~/.profile, ~/.bash_profile). 앱 사용자의 다음 인터랙티브 로그인 시 실행됩니다.
  • ~/.ssh/authorized_keys에 추가. 앱 사용자 권한으로 호스트에 대한 지속적인 SSH 접근을 부여합니다.

웹 계층 영향

  • 제공되는 JavaScript(예: site-packages의 Dash 프레임워크 JS)를 덮어써 호스트 도메인에서 저장형 크로스사이트 스크립팅을 유발하며, 애플리케이션이 재시작될 때까지 모든 페이지 로드에서 모든 사용자에게 영향을 줍니다
  • 애플리케이션 소스 코드 덮어쓰기(배포 메커니즘이 영향을 받는 경로를 완전히 덮어쓰지 않을 경우 일반적인 배포 후에도 살아남는 조용하고 지속적인 백도어)

파일시스템 영향

  • 정화되지 않은 resumableIdentifier 매개변수를 사용한 os.makedirs()를 통해 프로세스가 접근할 수 있는 모든 곳에 임의의 디렉터리 생성(inode 고갈 또는 존재하지 않는 디렉터리 트리에 쓰기를 준비하는 데 사용 가능)
  • 공유 업로드 디렉터리에서 사용자 간 파일 교체로, 동일한 애플리케이션의 테넌트 간 데이터 오염 유발

영향을 받는 구성 요소

  • dash_uploader/httprequesthandler.py
  • BaseHttpRequestHandler.get_temp_root()
  • BaseHttpRequestHandler._post()

완화 조치

⚠️ 패치가 제공되지 않으며 프로젝트는 보관되었습니다

현재 배포 중인 사용자를 위한 옵션은 선호 순서대로 다음과 같습니다:

  1. dcc.Upload로 마이그레이션 — Plotly Dash와 함께 제공되는 공식 업로드 컴포넌트입니다. 파일은 base64 문자열로 콜백에 도착하며, 파일시스템에 쓰는 핸들러가 노출되지 않고 클라이언트가 제어하는 대상 경로도 없으므로 이 버그 유형은 적용되지 않습니다. 중소형 파일에 가장 적합합니다. 매우 큰 업로드의 경우 항목 2를 참조하세요.

  2. 소규모 Flask 업로드 핸들러를 직접 작성 — werkzeug.utils.secure_filename()과 하드코딩된 서버 측 대상 디렉터리를 사용하세요. 클라이언트가 제공한 upload_id, 파일명, 식별자 값을 경로 구성 요소로 절대 허용하지 마세요.

  3. dash-uploader를 계속 사용해야 한다면 업로드 엔드포인트를 인증 뒤에 배치하고, 라이브러리 핸들러가 요청을 보기 전에 요청을 재작성하거나 거부하는 계층에서 upload_id, resumableFilename, resumableIdentifier를 엄격한 허용 목록(예: UUID만)으로 검증하세요. 라이브러리의 http_request_handler 훅은 훅이 반환된 후 매개변수가 request.form에서 읽히기 때문에 경로 탐색을 막지 못합니다. 정화(sanitization)는 라이브러리 위 계층에서 수행되어야 합니다.

  4. 리버스 프록시 또는 WAF 계층에서 업로드 엔드포인트에 대한 요청 중 어떤 폼 필드에 .., 인코딩된 변형(%2e%2e, ..%2f, %2e%2e%2f) 또는 절대 경로가 포함된 요청을 거부하세요.

공개 타임라인

날짜이벤트
2026-03-17프로덕션 배포 환경에 대한 보안 연구 중 취약점 발견.
2026-03-19MITRE에 CVE 요청 제출.
2026-05-07MITRE가 CVE-2026-38360 배정.
2026-05-07공개 권고 게시.
2026-05-09CVE 레코드가 MITRE CVE 데이터베이스와 NVD에 게시됨.

패키지 정보

  • PyPI에서 월 약 28,000건의 다운로드(2026-05-07 이전 30일 동안 27,756건, 저장소 보관에도 불구하고 일일 볼륨이 지속됨). 출처: pypistats.org.
  • 최신 공개 버전: 0.6.1(안정 버전 라인). 사전 릴리스는 0.7.0a2까지 있습니다.
  • 필수 의존성: dash. 선택 의존성: pyyaml. 라이선스: MIT.
  • 의존 패키지 11개, 의존 저장소 6개.
  • GitHub 스타 153개.
  • 저장소는 2025-07-19에 보관됨 (Issue #153).
  • 이전 CVE 없음(2026-03-19 기준 NVD, GitHub Advisory Database, Snyk, OSV에서 확인).

참고 자료

  • https://www.cve.org/CVERecord?id=CVE-2026-38360
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38360
  • https://github.com/fohrloop/dash-uploader
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/blob/dev/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://cwe.mitre.org/data/definitions/22.html

발견자

Muhammad Fitri Bin Mohd Sultan

도구 다운로드