Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rthooks: secure temp directories used by matplotlib and win32com rthooks #7827

Merged
merged 1 commit into from Aug 7, 2023

Conversation

rokm
Copy link
Member

@rokm rokm commented Aug 6, 2023

The run-time hooks that relocate the package's configuration/cache directory into isolated temporary directory create this directory using the tempfile.mkdtemp function. According to its documentation, the function creates the temporary directory "in the most secure manner possible", and the created directory should be "readable, writable, and searchable only by the creating user ID".

However, this does not apply to Windows, where the 0o700 POSIX permissions mask passed to the underyling os.mkdir call has no effect. Consequently, the access to the created temporary directory is in fact gated only by the access to the parent directory. So as long as TEMP and TMP point to %LOCALAPPDATA%\Temp, the created temporary directories are typically inaccessible to other users, who do not have access to the user's home directory. On the other hand, if the temporary directory base is relocated to a system-wide location (e.g., c:\temp), the temporary directories created by the run-time hooks might become accessible to other users as well. A malicious user with local access might thus modify the contents of the temporary directory, interfering with the application. If the application is running in privileged mode and developer mode is enabled on the system, they might also attempt a symlink attack due to lack of hardened mode for shutil.rmtree (used for clean up) on Windows.

Therefore, we replace the use of tempfile.mkdtemp with custom function that uses original mkdtemp on POSIX and provides a Windows-specific implementation that secures the access to created directory via security descriptor passed to the CreateDirectoryW call. This is a ctypes-based port of the code that we already have in bootloader for mitigating the same issue with temporary directory in onefile builds.

In order to share the implementation among the two run-time hooks that require it, the code is provided by a new _pyi_rth_utils PyInstaller "fake" package, which is bundled with the frozen application on demand (i.e., if it is referenced in any of collected run-time hooks).

The run-time hooks that relocate the package's configuration/cache
directory into isolated temporary directory create this directory using
the `tempfile.mkdtemp` function. According to its documentation, the
function creates the temporary directory "in the most secure manner
possible", and the created directory should be "readable, writable, and
searchable only by the creating user ID".

However, this does not apply to Windows, where the 0o700 POSIX
permissions mask passed to the underyling `os.mkdir` call has no effect.
Consequently, the access to the created temporary directory is in fact
gated only by the access to the parent directory. So as long as `TEMP`
and `TMP` point to `%LOCALAPPDATA%\Temp`, the created temporary
directories are typically inaccessible to other users, who do not have
access to the user's home directory. On the other hand, if the temporary
directory base is relocated to a system-wide location (e.g., `c:\temp`),
the temporary directories created by the run-time hooks might become
accessible to other users as well. A malicious user with local access
might thus modify the contents of the temporary directory, interfering
with the application. If the application is running in privileged mode
and developer mode is enabled on the system, they might also attempt
a symlink attack due to lack of hardened mode for `shutil.rmtree`
(used for clean up) on Windows.

Therefore, we replace the use of `tempfile.mkdtemp` with custom function
that uses original `mkdtemp` on POSIX and provides a Windows-specific
implementation that secures the access to created directory via security
descriptor passed to the `CreateDirectoryW` call. This is a
`ctypes`-based port of the code that we already have in bootloader for
mitigating the same issue with temporary directory in onefile builds.

In order to share the implementation among the two run-time hooks that
require it, the code is provided by a new `_pyi_rth_utils` PyInstaller
"fake" package, which is bundled with the frozen application on demand
(i.e., if it is referenced in any of collected run-time hooks).
@rokm rokm marked this pull request as ready for review August 7, 2023 09:23
@rokm rokm requested a review from bwoodsend August 7, 2023 09:23
@rokm rokm merged commit 5a53dc5 into pyinstaller:develop Aug 7, 2023
18 checks passed
@rokm rokm deleted the rthooks-secure-mkdtemp branch August 7, 2023 23:17
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants