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

Restrict Windows DLL search path as a precaution against DLL pre-loading attacks #56056

Open
cpeterso opened this Issue Nov 19, 2018 · 7 comments

Comments

Projects
None yet
8 participants
@cpeterso
Copy link
Contributor

cpeterso commented Nov 19, 2018

Windows' standard DLL search path contains directories that can be vulnerable to DLL pre-loading attacks. An application can use the SetDefaultDllDirectories API to specify a default DLL search path for the process that eliminates the most vulnerable directories and limits the other directories that are searched.

For example, as a precaution, Firefox removes the current directory from the DLL search path and then restricts the DLL search path to the application's installation directory, the Windows system directory, and any paths explicitly added using the AddDllDirectory or SetDllDirectory APIs.

https://searchfox.org/mozilla-central/rev/5117a4c4e29fcf80a627fecf899a62f117368abf/toolkit/mozapps/update/updater/loaddlls.cpp#15-30

https://searchfox.org/mozilla-central/rev/5117a4c4e29fcf80a627fecf899a62f117368abf/security/sandbox/chromium/sandbox/win/src/process_mitigations.cc#46-58

To help protect against DLL pre-loading attacks, the Rust compiler could emit similar code to restrict its DLL search path for all Windows Rust programs. Changing the DLL search path could cause compatibility problems for Windows Rust programs that assume they can implicitly load DLLs in the current directory without explicitly configuring their DLL search path. The workaround is for those programs to configure their DLL search path using the the AddDllDirectory or SetDllDirectory APIs.

See MSDN for SetDefaultDllDirectories:

https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-setdefaultdlldirectories

@SoniEx2

This comment has been minimized.

Copy link

SoniEx2 commented Nov 19, 2018

would this cause issues with e.g. steam overlay?

@csmoe csmoe added the O-windows label Nov 19, 2018

@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Nov 19, 2018

I feel that this specific change is out-of-scope for the Rust’s standard library. The standard library consciously avoids dealing with dynamic library loading. Therefore, the only DLLs that will be loaded without bringing in a crate (or calling winapi APIs directly) will be those that were dynamically linked to as part of building. Those libraries will not be affected by SetDefaultDllDirectories in any way.

To me it seems that the more appropriate location to do this would be in libraries that wrap/implement dynamic library loading or, in case winapi APIs are being called directly, by the caller.

@DemiMarie

This comment has been minimized.

Copy link
Contributor

DemiMarie commented Nov 22, 2018

@nagisa I disagree. SetDefaultDllDirectories is a Windows API, and so will always be present. Furthermore, it modifies global state, so I suspect that it is best to call it as early as possible. Rust can inject a call to it before main ever runs.

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Nov 22, 2018

All normal DLL dependencies are loaded and their symbols resolved before main is ever called. All C++ static initializers are also run before main is ever called, so Rust never has a chance to call SetDefaultDllDirectories before that stuff happens. Rust does actually LoadLibrary a few DLLsitself though but they're all known system DLLs that wouldn't be affected by SetDefaultDllDirectories anyway.

Having Rust implicitly call SetDefaultDllDirectories would bring in the possibility of breaking existing programs that rely on the default DLL search order, and from experience I can say that trying to figure out why a DLL can no longer be found is an incredibly frustrating ordeal.

I disagree. SetDefaultDllDirectories is a Windows API, and so will always be present.

      // SetDefaultDllDirectories is always available on Windows 8 and above. It
      // is also available on Windows Vista, Windows Server 2008, and
      // Windows 7 when MS KB2533623 has been applied.

This doesn't quite sound like always present.

@DemiMarie

This comment has been minimized.

Copy link
Contributor

DemiMarie commented Nov 23, 2018

Could Rust run SetDefaultDllDirectories from a static initializer?

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Nov 24, 2018

The order of C++ static initializers is not well defined, so there's no guarantee that an initializer in one compilation unit will run before an initializer in a different compilation unit.

@mirh

This comment has been minimized.

Copy link

mirh commented Jan 12, 2019

SetDefaultDllDirectories is not a security feature.
https://blogs.msdn.microsoft.com/oldnewthing/20170126-00/?p=95265#comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.