Skip to content

Improve the safety of the cache filename construction mechanism. - #3110

Merged
freakboy3742 merged 2 commits into
beeware:mainfrom
freakboy3742:win-path-traversal
Oct 26, 2026
Merged

freakboy3742 merged 2 commits into
beeware:mainfrom
freakboy3742:win-path-traversal

Conversation

@freakboy3742

Copy link
Copy Markdown
Member

When downloading a file, the cached filename is based on the Content-Disposition header, or the server-provided URL in the response. The strategy used to construct the cache filename was based on using / as filename separator. However, if the user is on Windows, \ is a valid filename separator. A path of ..\evil.exe will be parsed as a valid cache filename in the parent directory of the download location. An attacker can use this approach to construct an arbitrary location on the user's machine and write content to that location.

If the file has hash verification, the file will not be written unless the hash matches. However a temporary file with a .download extension will be created in same directory.

This PR modifies the cache name construction process so that it will:

  • use both / and \ as a basis for extracting the filename.
  • strip any leading or trailing spaces or periods in the name
  • reject any filename that contains a : (since this will be used to reference Windows drives, or NTFS alternate resource streams)
  • reject any empty filename
  • reject any attempt to reference the current or parent directory
  • reject any filename longer than 200 characterrs
  • reject any filename that is from the Windows device set.

It also modifies the temporary file creation process so that the temporary filename isn't affected by the cache name.

This is a mitigation for GHSA-j2qc-j92x-qqhj (to be announced shortly). A CVE has been requested.

Thanks to @fjjjuv for reporting this issue, and for their assistance reviewing this draft PR.

PR Checklist:

  • I will abide by the BeeWare Code of Conduct
  • I have read and have followed the CONTRIBUTING.md file
  • This PR was generated or assisted using an AI tool
    Assisted-by: Claude Opus 5.5

When downloading a file, the cached filename is based on the
`Content-Disposition` header, or the server-provided URL in the response. The
strategy used to construct the cache filename was based on using `/` as filename
separator. However, if the user is on Windows, `\` is a valid filename
separator. A path of `..\evil.exe` will be parsed as a valid cache filename in
the parent directory of the download location. An attacker can use this approach
to construct an arbitrary location on the user's machine and write content to
that location.

If the file has hash verification, the file will *not* be written unless the
hash matches. However a temporary file with a `.download` extension will be
created in same directory.

This PR modifies the cache name construction process so that it will:
* use both `/` and `\` as a basis for extracting the filename.
* strip any leading or trailing spaces or periods in the name
* reject any filename that contains a `:` (since this will be used to reference
  Windows drives, or NTFS alternate resource streams)
* reject any empty filename
* reject any attempt to reference the current or parent directory
* reject any filename longer than 200 characterrs
* reject any filename that is from the Windows device set.

It also modifies the temporary file creation process so that the temporary
filename isn't affected by the cache name.

This is a mitigation for GHSA-j2qc-j92x-qqhj / CVE TBA.
@freakboy3742
freakboy3742 merged commit 009d892 into beeware:main Oct 26, 2026
56 checks passed
@freakboy3742
freakboy3742 deleted the win-path-traversal branch October 26, 2026 23:18
freakboy3742 added a commit to Skytuhua/briefcase that referenced this pull request Oct 28, 2026
…ware#3110)

When downloading a file, the cached filename is based on the
`Content-Disposition` header, or the server-provided URL in the response. The
strategy used to construct the cache filename was based on using `/` as filename
separator. However, if the user is on Windows, `\` is a valid filename
separator. A path of `..\evil.exe` will be parsed as a valid cache filename in
the parent directory of the download location. An attacker can use this approach
to construct an arbitrary location on the user's machine and write content to
that location.

If the file has hash verification, the file will *not* be written unless the
hash matches. However a temporary file with a `.download` extension will be
created in same directory.

This PR modifies the cache name construction process so that it will:
* use both `/` and `\` as a basis for extracting the filename.
* strip any leading or trailing spaces or periods in the name
* reject any filename that contains a `:` (since this will be used to reference
  Windows drives, or NTFS alternate resource streams)
* reject any empty filename
* reject any attempt to reference the current or parent directory
* reject any filename longer than 200 characterrs
* reject any filename that is from the Windows device set.

It also modifies the temporary file creation process so that the temporary
filename isn't affected by the cache name.

This is a mitigation for GHSA-j2qc-j92x-qqhj.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant