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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-38361 — 권고: CVE-2026-38361 dash-uploader (Python/PyPI)의 여러 DoS 취약점 (CWE-400/CWE-670) | Kitploit
도구/GitHubGitHub/a1ohadance/cve-2026-38361
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingLearning & Education
GitHuba1ohadance/cve-2026-38361

CVE-2026-38361

권고: CVE-2026-38361 dash-uploader (Python/PyPI)의 여러 DoS 취약점 (CWE-400/CWE-670)

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-38361: dash-uploader의 다중 인증되지 않은 DoS 취약점

CVE NVD CWE-400 CWE-670 Severity Patch Auth Version

PyPI Downloads
Total Downloads
License

fohrloop/dash-uploader (Python, PyPI)에서 발견된 다중 인증되지 않은 서비스 거부(DoS) 문제로, (이에 국한되지 않음) 메모리 부족(OOM) 프로세스 충돌, 파일을 0바이트로 자르기, 영구적인 디스크 고갈, 문서화된 max_file_size 제한의 완전한 우회 등을 포함합니다. 동일한 무결한 매개변수 집합을 통해 추가 리소스 남용 경로가 존재합니다.

⚠️ 패치가 없으며, 절대 출시되지 않을 것입니다

저장소는 2025-07-19에 아카이브되었으며 활성 관리자가 없습니다. 출시된 모든 버전(0.1.0부터 0.7.0a2까지)이 영향을 받으며 앞으로도 그럴 것입니다. 이 패키지는 여전히 월간 약 28,000회 다운로드됩니다.

프로덕션에서 dash-uploader를 실행하는 사람은 스스로 완화 조치를 적용해야 합니다. 권장되는 수정 방법은 Plotly Dash의 내장 dcc.Upload 구성 요소로 마이그레이션하는 것입니다. 전체 옵션은 완화 조치를 참조하세요.

CVE IDCVE-2026-38361 (NVD)
취약점통제되지 않은 리소스 소비 (CWE-400), 항상 잘못된 제어 흐름 구현 (CWE-670)
CVSS 3.17.5 / 높음 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
제품dash-uploader
영향받는 버전0.1.0부터 0.7.0a2까지 (전체 18개 릴리스)
수정 버전없음 (프로젝트가 2025-07-19에 아카이브됨)
공격 벡터원격, 인증되지 않음
발견자Muhammad Fitri Bin Mohd Sultan
할당 기관MITRE, 2026-05-07
관련CVE-2026-38360 (동일 라이브러리의 경로 순회)

설명

dash-uploader HTTP 핸들러는 바운드 검사, 속도 제한, 정리 메커니즘 없이 메모리 할당, 파일 작업 및 디렉토리 생성으로 이어지는 공격자 제어 매개변수가 포함된 인증되지 않은 POST 요청을 허용합니다. 동일한 코드 경로에 4가지 독립적인 문제가 있습니다.

1. OOM 충돌 (확인됨)

7.7GB 시스템에서 확인됨: resumableTotalChunks=30000000이 포함된 5개의 동시 POST 요청이 2초 이내에 Linux OOM 킬러를 트리거했습니다. 커널 로그에서 확인됨:

root@kitploit:~
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB

각 요청은 range(1, resumableTotalChunks + 1)에 대한 리스트 컴프리헨션을 통해 약 2.9GB를 할당합니다. 서버 프로세스가 종료되고 수동 재시작이 있을 때까지 애플리케이션을 완전히 사용할 수 없게 됩니다.

2. 파일 잘림 (확인됨)

42바이트의 데이터를 포함한 파일이 resumableTotalChunks=0인 단일 POST 요청을 통해 0바이트로 축소되었습니다. 근본 원인은 Python의 all()이 빈 반복 가능 객체에 대해 True를 반환하여 업로드 핸들러가 0개의 청크를 완료된 업로드로 처리하도록 속이는 것입니다. 기존 파일은 os.unlink()를 통해 삭제되고 빈 파일로 대체됩니다.

3. 중단된 업로드 누적 (확인됨)

청크 파일이 있는 10개의 고아 임시 디렉토리가 디스크에 영구적으로 생성되어 지속되었습니다. 모든 소스 파일에서 cleanup, ttl, expire, garbage, purge, cron, schedule, periodic에 대한 코드베이스 전체 검색에서 0개의 결과가 반환되었습니다. 유일한 정리 호출(shutil.rmtree)은 완료된 업로드에만 독점적으로 실행됩니다. 불완전한 세션에서 디스크 공간을 회수하는 메커니즘이 없습니다.

4. max_file_size 우회 (확인됨)

서버가 HTTP 200으로 resumableTotalSize=999999999999(~999GB)를 주장하는 파일에 대해 5MB 청크를 수락했습니다. max_file_size 매개변수는 React JavaScript 구성 요소에만 전달됩니다. 서버는 파일 크기, 청크 크기, Content-Length 또는 Flask MAX_CONTENT_LENGTH를 절대 확인하지 않습니다. max_file_size=10을 설정한 개발자는 서버 측 보호 기능이 없습니다.

취약한 코드

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableTotalChunks = request.form.get("resumableTotalChunks", type=int)   # 공격자 제어, 바운드 없음
    ...
    chunk_paths = [
        os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
        for x in range(1, resumableTotalChunks + 1)                              # 바운드 없음; 예: 30M -> ~2.9 GB -> OOM
    ]
    upload_complete = all([os.path.exists(p) for p in chunk_paths])              # all([])은 True -> 청크가 0이면 잘림
    if upload_complete:
        target_file_name = os.path.join(temp_root, resumableFilename)
        if os.path.exists(target_file_name):
            os.unlink(target_file_name)                                          # 기존 파일 삭제
        with open(target_file_name, "ab") as target_file:
            for p in chunk_paths:                                                # 빈 리스트 -> 빈 파일 기록
                ...

동일한 코드 경로가 OOM(큰 resumableTotalChunks)과 파일 잘림 프리미티브(resumableTotalChunks=0)를 모두 생성합니다.

공격 벡터

공격자는 /API/resumable 엔드포인트에 인증되지 않은 POST 요청을 보냅니다.

  • OOM 충돌: resumableTotalChunks=30000000이 포함된 5개의 동시 요청이 각각 약 2.9GB를 할당하여 OOM 킬러를 트리거합니다.
  • 디스크 고갈: 업로드를 시작하지만 완료하지 않습니다. 고아 임시 파일이 영원히 누적됩니다.
  • 파일 잘림: resumableTotalChunks=0을 보냅니다. Python all([])=True가 서버를 속여 대상 파일을 빈 내용으로 덮어씁니다.
  • 크기 우회: 개발자가 설정한 모든 크기 제한은 클라이언트 JavaScript에서만 적용되므로 직접적인 HTTP 요청이 이를 완전히 우회합니다.

인증이나 권한이 필요하지 않습니다.

영향

  • 단일 사용자 제어 POST 매개변수(resumableTotalChunks)의 무제한 메모리 할당으로 인한 Linux OOM 킬러를 통한 서버 프로세스 충돌
  • 정리되지 않은 중단된 업로드 세션으로 인한 영구적인 디스크 고갈 (코드베이스에 TTL, 가비지 수집, 만료 메커니즘 없음)
  • 무결한 resumableIdentifier로 os.makedirs()를 통한 임의 깊이 디렉토리 생성으로 인한 파일 시스템 inode 고갈
  • resumableTotalChunks=0일 때 빈 반복 가능 객체에 대해 Python all()이 True를 반환하여 발생하는 파일 0바이트 잘림을 통한 데이터 파괴
  • max_file_size가 클라이언트 측 JavaScript에서만 적용되고 서버 측 핸들러가 크기 검증을 전혀 수행하지 않으며 Flask MAX_CONTENT_LENGTH를 설정하지 않기 때문에 모든 파일 크기 제한 우회

영향을 받는 구성 요소

  • dash_uploader/httprequesthandler.py (BaseHttpRequestHandler._post 메서드)
  • dash_uploader/upload.py (Upload 함수, max_file_size 매개변수)
  • dash_uploader/configure_upload.py (누락된 MAX_CONTENT_LENGTH)

완화 조치

⚠️ 패치가 없으며, 프로젝트가 아카이브되었습니다

현재 배포된 사용자를 위한 선호도 순 옵션:

  1. dcc.Upload로 마이그레이션: Plotly Dash와 함께 제공되는 공식 업로드 구성 요소입니다. 청크 수 매개변수, 디스크상 임시 상태가 없으며 Flask MAX_CONTENT_LENGTH를 준수합니다. 여기에 있는 4가지 문제 중 어느 것도 적용되지 않습니다. 중소형 파일에 가장 적합합니다. 매우 큰 업로드의 경우 항목 2를 참조하세요.
  2. 작은 Flask 업로드 핸들러 구현: 명시적인 요청당 크기 제한(MAX_CONTENT_LENGTH), 클라이언트가 제공하는 청크 수에 대한 바운드, 허용된 파일 이름에 대한 허용 목록을 포함합니다.
  3. 계속 dash-uploader를 사용하는 경우: 애플리케이션 수준에서 Flask MAX_CONTENT_LENGTH를 설정하고(라이브러리가 설정하지 않음), 다음 조건 중 하나라도 해당되는 경우 애플리케이션 또는 리버스 프록시 계층에서 입력을 거부합니다.
    • resumableTotalChunks <= 0
    • resumableTotalChunks가 합리적인 바운드를 초과하는 경우(예: 10,000)
    • resumableTotalSize가 개발자가 구성한 max_file_size를 초과하는 경우
  4. 업로드 엔드포인트에 속도 제한 추가: 동시 요청 OOM 벡터를 완화하기 위해 리버스 프록시 또는 WAF 계층에서 속도 제한을 추가합니다.
  5. 외부 cron 작업으로 고아 임시 디렉토리를 주기적으로 정리: 라이브러리에 내부 정리 기능이 없으므로 필요합니다.

공개 타임라인

날짜이벤트
2026-03-19프로덕션 배포에 대한 보안 연구 중 취약점 발견.
2026-03-22MITRE에 CVE 요청 제출.
2026-05-07MITRE에서 CVE-2026-38361 할당.
2026-05-07공개 권고 게시.
2026-05-09MITRE CVE 데이터베이스 및 NVD에 CVE 레코드 게시.

패키지 컨텍스트

  • 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에 아카이브됨 (이슈 #153).
  • 이전 CVE 없음 (2026-03-19 기준 NVD, GitHub Advisory Database, Snyk, OSV에서 확인됨).

참고 자료

  • https://www.cve.org/CVERecord?id=CVE-2026-38361
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38361
  • https://github.com/fohrloop/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://libraries.io/pypi/dash-uploader
  • https://pepy.tech/project/dash-uploader
  • https://cwe.mitre.org/data/definitions/400.html
  • https://cwe.mitre.org/data/definitions/670.html
  • https://docs.python.org/3/library/functions.html#all

발견자

Muhammad Fitri Bin Mohd Sultan

도구 다운로드