
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 コンポーネントへの移行です。詳細な選択肢については 緩和策 を参照してください。
dash-uploader の HTTP ハンドラは、攻撃者が制御するパラメータを含む未認証の POST リクエストを受け入れます。これらのパラメータは、境界チェック、レート制限、クリーンアップ機構が一切ないまま、メモリ割り当て、ファイル操作、ディレクトリ作成に流れ込みます。同じコードパスに 4 つの独立した問題があります。
7.7 GB のシステムで検証済み: resumableTotalChunks=30000000 を指定した 5 つの同時 POST リクエストにより、2 秒以内に Linux の OOM killer が発動しました。カーネルログは以下を裏付けています:
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB
各リクエストは range(1, resumableTotalChunks + 1) に対するリスト内包表記により約 2.9 GB を割り当てます。サーバープロセスは終了し、アプリケーションは手動での再起動まで完全に利用不能になります。
42 バイトのデータを含むファイルが、resumableTotalChunks=0 を指定した 1 つの POST リクエストによって 0 バイトに縮小されました。根本原因は、Python の all() が空のイテラブルに対して True を返すことであり、これによりアップロードハンドラがゼロチャンクを完了したアップロードとして扱ってしまいます。既存のファイルは os.unlink() で削除され、空のファイルに置き換えられます。
チャンクファイルを含む 10 個の孤立した一時ディレクトリが作成され、ディスク上に無期限に残り続けました。全ソースファイルに対するコードベース全体での cleanup、ttl、expire、garbage、purge、cron、schedule、periodic の検索では、結果はゼロでした。唯一のクリーンアップ呼び出し (shutil.rmtree) は完了したアップロードでのみ実行されます。未完了のセッションからディスク領域を回収する機構はありません。
max_file_size バイパス (検証済み)サーバーは、resumableTotalSize=999999999999 (約 999 GB) を主張するファイルの 5 MB チャンクを HTTP 200 で受け入れました。max_file_size パラメータは React JavaScript コンポーネントにのみ渡されます。サーバーはファイルサイズ、チャンクサイズ、Content-Length、Flask の MAX_CONTENT_LENGTH を一切チェックしません。開発者が max_file_size=10 を設定しても、サーバー側の保護はまったくありません。
# dash_uploader/httprequesthandler.py
def _post(self):
resumableTotalChunks = request.form.get("resumableTotalChunks", type=int) # attacker-controlled, no bounds
...
chunk_paths = [
os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
for x in range(1, resumableTotalChunks + 1) # unbounded; e.g. 30M -> ~2.9 GB -> OOM
]
upload_complete = all([os.path.exists(p) for p in chunk_paths]) # all([]) is True -> truncation when chunks=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) # existing file deleted
with open(target_file_name, "ab") as target_file:
for p in chunk_paths: # empty list -> empty file written
...
同じコードパスが、OOM (大きな resumableTotalChunks) とファイル切り詰めプリミティブ (resumableTotalChunks=0) の両方を生み出します。
攻撃者は /API/resumable エンドポイントに未認証の POST リクエストを送信します。
resumableTotalChunks=30000000 を指定した 5 つの同時リクエストがそれぞれ約 2.9 GB を割り当て、OOM killer を発動させます。resumableTotalChunks=0 を送信します。Python の all([])=True により、サーバーは対象ファイルを空の内容で上書きしてしまいます。認証や特権は不要です。
resumableTotalChunks) による無制限のメモリ割り当てがトリガーとなる、Linux OOM killer によるサーバープロセスのクラッシュ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 の欠落)現在デプロイ中のユーザー向けの選択肢を、優先順位の高い順に示します:
dcc.Upload への移行: Plotly Dash に同梱されている公式のアップロードコンポーネントです。チャンク数パラメータがなく、ディスク上の一時状態も持たず、Flask の MAX_CONTENT_LENGTH を尊重します。ここに挙げた 4 つの問題はいずれも該当しません。小規模から中規模のファイルに最適です。非常に大きなアップロードについては項目 2 を参照してください。MAX_CONTENT_LENGTH)、クライアントが指定するチャンク数の上限、受け付けるファイル名の許可リストを備えます。MAX_CONTENT_LENGTH をアプリケーションレベルで設定し (ライブラリは設定しません)、以下のいずれかに該当する入力をアプリケーションまたはリバースプロキシ層で拒否してください:
resumableTotalChunks <= 0resumableTotalChunks が妥当な上限 (例: 10,000) を超えているresumableTotalSize が開発者が設定した max_file_size を超えている0.6.1 (安定版ライン)。プレリリースは 0.7.0a2 まで。dash。任意依存関係: pyyaml。ライセンス: MIT。Muhammad Fitri Bin Mohd Sultan
| CVE ID | CVE-2026-38361 (NVD) |
| 脆弱性 | リソース消費の制御不能 (CWE-400)、常に誤った制御フロー実装 (CWE-670) |
| CVSS 3.1 | 7.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 (同一ライブラリのパストラバーサル) |
| 日付 | イベント |
|---|
| 2026-03-19 | 本番環境へのデプロイに対するセキュリティ調査中に脆弱性を発見。 |
| 2026-03-22 | CVE リクエストを MITRE に提出。 |
| 2026-05-07 | MITRE により CVE-2026-38361 が割り当てられる。 |
| 2026-05-07 | 公開アドバイザリを公開。 |
| 2026-05-09 | CVE レコードが MITRE CVE データベース と NVD に公開。 |