VYPR
Medium severity5.9NVD Advisory· Published Apr 8, 2026· Updated Apr 15, 2026

CVE-2026-39844

CVE-2026-39844

Description

NiceGUI is a Python-based UI framework. Prior to 3.10.0, Since PurePosixPath only recognizes forward slashes (/) as path separators, an attacker can bypass this sanitization on Windows by using backslashes (\) in the upload filename. Applications that construct file paths using file.name (a pattern demonstrated in NiceGUI's bundled examples) are vulnerable to arbitrary file write on Windows. This vulnerability is fixed in 3.10.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
niceguiPyPI
< 3.10.03.10.0

Affected products

1

Patches

1
d38a702e3af2

Merge commit from fork

https://github.com/zauberzeug/niceguiEvan ChanApr 7, 2026via ghsa
2 files changed · +20 2
  • nicegui/elements/upload_files.py+7 2 modified
    @@ -3,7 +3,7 @@
     from collections.abc import AsyncIterator
     from dataclasses import dataclass
     from io import BytesIO
    -from pathlib import Path, PurePosixPath
    +from pathlib import Path
     
     import aiofiles
     import anyio
    @@ -149,8 +149,13 @@ async def create_file_upload(upload: UploadFile, *, chunk_size: int = 1024 * 102
             if temp_file:
                 await temp_file.close()
     
    -    filename = PurePosixPath(upload.filename or '').name  # strips all path components
    +    filename = _sanitize_filename(upload.filename)
         if temp_file:
             return LargeFileUpload(filename, upload.content_type or '', Path(str(temp_file.name)))
         else:
             return SmallFileUpload(filename, upload.content_type or '', buffer.getvalue())
    +
    +
    +def _sanitize_filename(name: str | None) -> str:
    +    """Strip all path components from a filename to prevent path traversal."""
    +    return (name or '').rsplit('/')[-1].rsplit('\\')[-1]
    
  • tests/test_upload.py+13 0 modified
    @@ -3,6 +3,7 @@
     import pytest
     
     from nicegui import events, ui
    +from nicegui.elements.upload_files import _sanitize_filename
     from nicegui.testing import Screen
     
     test_path1 = Path('tests/test_upload.py').resolve()
    @@ -163,3 +164,15 @@ def page():
         screen.wait(0.1)
         assert reads[0].file.size() == size
         assert await reads[0].file.text() == tmp_file.read_text()
    +
    +
    +@pytest.mark.parametrize('input_name,expected', [
    +    ('simple.txt', 'simple.txt'),
    +    ('../../etc/passwd', 'passwd'),
    +    ('..\\..\\windows\\evil.exe', 'evil.exe'),
    +    ('../..\\..\\mixed/traversal\\payload.txt', 'payload.txt'),
    +    ('', ''),
    +    (None, ''),
    +])
    +def test_upload_filename_sanitization(input_name: str | None, expected: str):
    +    assert _sanitize_filename(input_name) == expected
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.