openssl / openssl

TLS/SSL and crypto library

Home Page:https://www.openssl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Windows, world-writable config path (re: CVE-2019-5443)

vszakats opened this issue · comments

This is a long time problem, and opening a new Issue to give it some
visibility and place to discuss.

OpenSSL loads its config (openssl.cnf) from a disk location baked
into the binary at build time (aka --openssldir=).

For the Windows platform this raises issues. Earlier OpenSSL versions
used the unixy (/usr/local) path by default, which lead to
CVE-2019-5443: https://curl.se/docs/CVE-2019-5443.html

The default was then changed (in 1.1.1d) to pick the Program Files
path as returned by the OS env variable at build time:

%ProgramFiles(x86)%
%CommonProgramFiles(x86)%
%ProgramFiles%
%CommonProgramFiles%\SSL

Notice this approach keeps the vulnerability in cross-builds.
There is no Windows OS env variable to rely on in those.

But it also has other issues. The bigger one is that the 'Program Files'
directory name is localized by Microsoft, and named differently
depending on the language of the OS:
https://en.wikipedia.org/wiki/Program_Files#Localization
(I could not find a Microsoft link, sorry)

These names are present on the file system and not just localized
on the UI level, like it is done by macOS Finder for example.

It means that an OpenSSL build has a world-writable config path
when copied to an OS with a 'Program Files' directory named
differently than the build machine. Building and running on different
machines is very common on the Windows platform.

(The smaller issue is the possible confusion for 32-bit and 64-bit
'Program Files' directories (there are two of them!) vs. 32/64-bit
builds running on these systems. But let's disregard that.)


Notice that I have not verified these with an actual localized Windows.

OpenSSL 1.1.1 introduced (in dbabc86 #5959) the no-autoload-config
build option in v1.1.1, but that broke in v3.0.0, and was only fixed in
v3.2.0 (cb8e641 #21621). While this most likely fixes the issue, it also
disables the config feature and it's also a non-default option, so it
comes with drawbacks and likely not enabled in most builds.

BoringSSL dropped support for an external config. LibreSSL also did
so around 3.8.x-ish for most functionality, so they are not affected.

Possible solutions:

  • Make no-autoload-config the default option for Windows.
  • Make no-autoload-config the only option for Windows.
  • Change the default directory to C:/Windows/System32/OpenSSL or similar.
    But, that is also not a guaranteed protected directory (Windows can/could
    be installed on D: for example), and storing 3rd-party configuration in
    the Windows directory isn't recommended anyway. This is what I've been
    doing for curl builds since the 2019 CVE. Also LibreSSL has been doing
    these for some time.
  • Determine the config location at runtime by querying the Win32 API for

    the actual Program Files directory name in the runtime environment
    (e.g. via SHGetSpecialFolderPath()).
    This seem to be the ideal solution, also keeping compatibility with the
    current, build-time, default (at least for English systems and similar
    ones).
  • Perhaps a combation of the above.

Unless I have missed something fundamental, this seems to need a fix so
that any builder is able to create binaries that are not vulnerable in
any Windows environment.

Let me know your thoughts, or if you have any questions.

/cc @levitte

PR #24450 seems relevant somehow to this discussion

see #24450

We're actively working on creating a windows installer which enables registry keys for both the install time defaults as well as run time environment variables to override them, so that both administrators and users can direct the location of OPENSSLDIR/ENGINESDIR/MODULESDIR

@nhorman Thanks!

I may be misunderstanding what that PR does and what "windows installer" means. If it means a classic installer, meaning a separate / one-time installation step that's setting up certain things while copying in OpenSSL binaries into place, I don't think it will fix this in a significant portion of the cases. On Windows, there is often no disctinct install process, just copying / unpacking a binary, esp. with command-line tools like OpenSSL. OpenSSL also frequently comes as a dependency of other tools, which may or may not have an installer phase (and may or more likely may not trigger the OpenSSL-specific install steps).

A one-time installer also has the downside that it requires a reinstall when migrating between machines.

Does that PR also have a component that makes the OpenSSL runtime dynamically adapt to the environment (without a one-time installer step)?

IMO this is a feature. Windows is unfortunately so inherently misdesigned as a multi-user system that I do not think you can call this a bug in OpenSSL. At least it is IMO not a bug in the sense that we would consider any implementation fixing this to be backported to existing stable releases.

And yeah IMO we will need some help in implementing the "dynamically adapt" feature.

OpenSSL 1.1.1 introduced (in dbabc86 #5959) the no-autoload-config
build option in v1.1.1, but that broke in v3.0.0, and was only fixed in
v3.2.0 (cb8e641 #21621).

This is fixed in all current stable releases AFAIK.

PR #24450 replaces the hard-coded config paths with reading them from new, OpenSSL-specific registry keys in HKLM. This definitely looks like an improvement.

Thinking of the 'no installer' scenario, it made me wonder how OpenSSL would behave if some or all of the OpenSSL-specific registry keys are missing?

by windows installer, I am specifically referring to this installer:
https://github.com/openssl/installer

The pr mentioned above works with the installer in that it references registry keys created (or soon to be created by the installer) to properly reference the created keys to find the OPENSSLDIR/MODULESDIR/ENGINESDIR directory for a given installation.

For a downstream consumer of openssl, theres really not much we can do for them, unless they as consumers properly set the environment variables that override these build time (now install time) defaults. with the change in the above PR they could of course modify those keys, but they would have to do so individually

For a no-installer scenario, we are in the same position as we were previously, in that, a registry key is queried, and, if not found, falls back to the build time defined default. An administrator would have to set the keys manually to override that, which they are welcome to do of course.

As for dynamic adaptation, I'm not sure what something like that would look like. The closest thing I could think of would be to require the setting of OPENSSL_CONF OPENSSL_ENGINES and OPENSSL_MODULES for the application in question.

IMO this is a feature. Windows is unfortunately so inherently misdesigned as a multi-user system that I do not think you can call this a bug in OpenSSL. At least it is IMO not a bug in the sense that we would consider any implementation fixing this to be backported to existing stable releases.

Windows has not featured a stable write-protected directory throughout it's existence. It's hard to see any other choice than dealing with this fact. Disregaring it is certainly unexpected and in this case has been the cause of a large, then in the last 5 years more limited, but still a grave (IMO) security issue.

IMO it'd be nice to backport it, because most are unlikely to start building with no-autoload-config. Upgrading to a recent 3.x version will also likely take many years for a lot of dependents. Of course it's up to OpenSSL to decide.

And yeah IMO we will need some help in implementing the "dynamically adapt" feature.

If the OpenSSL-specific HKLM keys are missing, OpenSSL could fall back to

  • the default path based on the SHGetSpecialFolderPath() system call.
    On English-language systems this would match existing behaviour.
    On systems with localized Program Files directory, it would make OpenSSL use the expected local directories, instead of the hard-coded Program Files directory, which didn't exist anyway (not out of the box that is).

  • not load anything from disk at all. This would break compatibility.

by windows installer, I am specifically referring to this installer: https://github.com/openssl/installer

I see. Didn't know about it, thanks.

The pr mentioned above works with the installer in that it references registry keys created (or soon to be created by the installer) to properly reference the created keys to find the OPENSSLDIR/MODULESDIR/ENGINESDIR directory for a given installation.

For a downstream consumer of openssl, theres really not much we can do for them, unless they as consumers properly set the environment variables that override these build time (now install time) defaults. with the change in the above PR they could of course modify those keys, but they would have to do so individually

For a no-installer scenario, we are in the same position as we were previously, in that, a registry key is queried, and, if not found, falls back to the build time defined default. An administrator would have to set the keys manually to override that, which they are welcome to do of course.

Why not detect the Program Files location at runtime?

As for dynamic adaptation, I'm not sure what something like that would look like. The closest thing I could think of would be to require the setting of OPENSSL_CONF OPENSSL_ENGINES and OPENSSL_MODULES for the application in question.

See my other message above: #24528 (comment)

because there is no guarantee that the installer will place the directory paths below the installer location. An administrator may select to place OPENSSLDIR in a common area, so that multiple installations can use the same certificate store for instance.

There is also no guarantee that the configs will be found under the existing hard-wired Program Files location. A missing config however doesn't cause any problem AFAIK.

The problem however is that on non-English systems, any non-admin user can fabricate a malicious config and make OpenSSL load any user supplied DLL. As demonstrated in CVE-2019-5443.

Detecting the config directory at runtime instead of relying on the hardcoded values would fix that, without causing additional issues compared to existing OpenSSL releases.

Ostensibly the use of registry keys under HKEY_LOCAL_MACHINE prevents that as well, as those registry keys should be write protected for any non-administrative user.

What happens if those HKLM keys don't exist?

we fall back to the build time defines for OPENSSLDIR/ENGINESDIR/MODULESDIR

we fall back to the build time defines for OPENSSLDIR/ENGINESDIR/MODULESDIR

It means that PR #24450 will not fix anything raised in this issue.

Not without application developers who include openssl as a component changing their install procedure, no.

But that seems ok. I don't want to go hardcoding a policy into openssl that impacts distirbutions in the field (at least not in a minor release like this). Such developers could have set OPENSSLDIR/ENGINESDIR/MODULESDIR to appropriate locations during their build previously, but now have the option of altering that at install time, which is an improvement over what they had previously (having to determine these locations at build time)

On Windows it's extremely rare that the build from source is done on the same machine where the resulting binaries are then used exclusively. This (unixy ?) concept is foreign, or rather the exception, on the Windows platform. This doesn't mix well with the notion of determining security-sensitive file locations at build time, when those paths are known to be machine-dependent.

Requiring an install phase does nothing more IMO than pushing the responsibility from OpenSSL authors (and/or builders) now to "installers". But such installer don't exist in a large portion of OpenSSL use-cases in the wild. It will not make OpenSSL binaries free of this vulnerability out of the box. Each machine will require an administrator to setup these HKLM keys manually or run an installer that does it. If OpenSSL happens to run on the machine without this extra step, the deployment remains open to the vulnerability.

But that seems ok. I don't want to go hardcoding a policy into openssl that impacts distirbutions in the field (at least not in a minor release like this).

Paths are already hardcoded in the OpenSSL binaries, and that is exactly the problem.

Can you tell why would it be a problem if OpenSSL actually read the Program Files locations at runtime instead of relying on a build-time preset?

I understand what your saying, but what you are suggesting is that making the file location a built in policy of openssl. I also understand what you are saying in that hardcoded paths are the problem on windows builds. This PR gives users the option at install time to specify those paths when the requisite openssl libraries are installed.

That downstream consumers don't use an installer is rather (IMHO), outside the scope of this work. If a downstream consumer chooses to install openssl libraries by simply copying files to a given location, well, now they have the option to incorporate another step, and set these requisite registry keys as part of the process (however they choose to do so, be it via their own installer program, or manually via the reg command, or something else), is their choice.

To incorporate a policy, such as you have suggested, to look for engines/providers/configs in the execution directory of the application being run, does a little to solve the build time issues illustrated, but does nothing to address the larger security issue (if a user installs to a world writeable path, its no more secure than what we have now).

In summary, its my view that we need a way to provide adminstrators installing openssl (or consuming applications) with a mechanism to specify where these directories are located when the install occurs. That necessitates those adminstrators and consuming applications to participate in that process, by specifying those paths during the install

To incorporate a policy, such as you have suggested, to look for engines/providers/configs in the execution directory of the application being run, does a little to solve the build time issues illustrated, but does nothing to address the larger security issue (if a user installs to a world writeable path, its no more secure than what we have now).

I haven't suggested that the config path should be inherited from an application.

What I'm suggesting is to replace the build-time hard-coded (potentially vulnerable) config paths, namely C:\Program Files*\:

$ grep -R ProgramFiles
./Configurations/windows-makefile.tmpl:     $install_flavour eq "VC-WOW" ? "ProgramFiles(x86)"
./Configurations/windows-makefile.tmpl:     $install_flavour eq "VC-WOW" ? "CommonProgramFiles(x86)"
./Configurations/windows-makefile.tmpl:     defined($ENV{$win_installenv}) ? $win_installenv : 'ProgramFiles';
./Configurations/windows-makefile.tmpl:     defined($ENV{$win_commonenv}) ? $win_commonenv : 'CommonProgramFiles';
./NOTES-WINDOWS.md:    PREFIX:      %ProgramFiles(x86)%\OpenSSL
./NOTES-WINDOWS.md:    OPENSSLDIR:  %CommonProgramFiles(x86)%\SSL
./NOTES-WINDOWS.md:    PREFIX:      %ProgramFiles%\OpenSSL
./NOTES-WINDOWS.md:    OPENSSLDIR:  %CommonProgramFiles%\SSL

with corresponding calls at runtime to
SHGetSpecialFolderPath(... CSIDL_PROGRAM_FILES ...) and
SHGetSpecialFolderPath(... CSIDL_PROGRAM_FILES_COMMON ...).

This would fix this issue without installation, while keeping compatibility, on all Windows machines, regardless of where and how the binaries were built.

Do you think this has any downside?

In summary, its my view that we need a way to provide adminstrators installing openssl (or consuming applications) with a mechanism to specify where these directories are located when the install occurs. That necessitates those adminstrators and consuming applications to participate in that process, by specifying those paths during the install

I agree that's useful in itself.

I do think it has downsides. If we fall back to a specific location (in this case the ShGetSpecialFolderPath location for CSIDL_COOMMON_APPDATA, say), Then we have created a canonical location for all openssl files, even if there are multiple openssl installations operating in parallel.

For example, lets say two applications, A and B have statically linked to libcrypto.a. Both of those applications need to be able to find the configs/engines/providers associated with that library (which may be different). By creating a single location for those to exist, one of them is guaranteed to use the configs/engines/providers of the other installation. We need to be able to handle that.

I understand the code I have in #24450 doesn't handle that yet either, I'm currently working on the ability to provide a versioned/suffixed key entry for each installation. That is to say, that we will be able to define at build time an INSTALLCONTEXT variable, that will be used by the library to lookup values in the HKLM\SOFTWARE\OpenSSL-- key.

By doing this, each consuming vendor will be able to look up keys specific to their installation (using installation here in the sense of libcrypto looking up keys, not the existance of an installer specifically). This will let us keep separate consumer files distinct.

I understand that many of these consuming applications don't contain installers (now using the term in the sense of an actual installer application), but its entirely possible to set these keys on the command line as necessecary.

What you're describing as a downside has already been shipping in OpenSSL for two decades including all the latest stable release versions, with or without my proposal. OpenSSL is using a directory hard-wired at build time, with insecure defaults.

A builder can customize this directory AT BUILD TIME, but this has very little (if any) use, because binaries can be installed anywhere, and "standard" paths vary between Windows machines. This build-time option also never solved the problem of separating configuration paths for OpenSSL dependencies, on Windows at least.

My proposal would IMO improve that by making these paths secure on every Windows env, by moving 'Program Files' detection from build-time to runtime.

What I'm asking is if this would cause any downsides compared to how OpenSSL works and worked in the last 20+ years?

What you mention is a different problem. For multiple OpenSSL installations, I think the solution is to provide a public API where dependents are able to set the configuration paths at runtime, e.g. to their own app directory. Indeed, #24450 doesn't solve that problem either. But, #24450 can be combined with secure defaults determined at runtime and also an API that lets dependends customize it at runtime.

your proposal replaces one problem with another. Currently, yes, I agree a hard coded build time path for OPENSSLDIR and friends creates a constraint in which engines/providers have to be placed in that directory for those paths to work properly at run time, and your proposal allows for the determination of that location to be made at run time instead, which is good.

But it creates a new problem in that, the run-time discovered directory is a single location, meaning that application developer that consume openssl now only have a single location in which to put those needed files. If we havve two applications which both consume openssl, which installation gets to put their files in that location? And how does the other location then work? Yes its a new and different problem, but its one that your solution introduces. Thats the downside. whereas previously developers were constrained by these defines in terms of their location installation, they would now be constrained to only allowing a single OPENSSLDIR path for all applications that link to openssl.

using application specific registry keys solves both, because each application can configure openssl with a unique windows install context to define the key path, and create their own install location. The selection of a secure location is of course now an administrative task, but thats needed, just as its needed to allows multiple openssl linked applications to supply their own default config/engine/provider locations

your proposal replaces one problem with another. Currently, yes, I agree a hard coded build time path for OPENSSLDIR and friends creates a constraint in which engines/providers have to be placed in that directory for those paths to work properly at run time, and your proposal allows for the determination of that location to be made at run time instead, which is good.

There doesn't exist any path that a builder can set, which is guaranteed to be secure (or work at all) on all Windows machines. This is the root issue.

But it creates a new problem in that, the run-time discovered directory is a single location, meaning that application

This problem is pre-existing behaviour and isn't created by my proposal. OpenSSL supports a single location with or without this proposal. The only difference is that without this proposal it uses a single location (existing or not) for all Windows machines, with the proposal it uses a single location determined for that specific machine, that is guaranteed to exist and be non-world-writable.

developer that consume openssl now only have a single location in which to put those needed files. If we havve two > applications which both consume openssl, which installation gets to put their files in that location? And how does the other > location then work? Yes its a new and different problem, but its one that your solution introduces. Thats the downside.

Correct me if I'm wrong, but I'm guessing you mean that build-time customization is the current solution for the "multiple location" problem? (and that would be lost with my proposal?)

I'd argue this option is mostly theoretical on Windows and doesn't solve the "multiple location" in practice:

  • most users use pre-built binaries, therefore no customization on their own. Building OpenSSL on Windows has been historically a pain. This has improved, but I don't think building it became widespread on the platform.
  • customizing the "prefix" is a huge pain in itself. Try passing a Windows path to ./Configure, esp with a space or drive designator in it, and see what happens. For cross-builds, customization wasn't working at all until very recently.
  • most importantly: build-time customization is unfit to resolve this problem on Windows. Applications do not know in advance in which directory they will be installed, therefore it's not possible to set any path reliably at build time.

I understand it may work in limited cases though (controlled envs, embedded for example).

This proposal doesn't say that the build-time configuration option must be removed. It can well stay when a --prefix/--openssldir is explicitly set at build time. And let this proposal kick in when building without a customized --prefix/--openssldir.

My proposal is also compatible with the idea of overriding the default path by a (per-user, per-install, per-app, etc) registry key or an API call, even though this particular issue is not about that.

using application specific registry keys solves both, because each application can configure openssl with a unique windows install context to define the key path, and create their own install location. The selection of a secure location is of course now an administrative task, but thats needed, just as its needed to allows multiple openssl linked applications to supply their own default config/engine/provider locations

A registry key doesn't solve this issue, because OpenSSL would fall back (as you said above) to the build-time default if the key isn't present. Which is the case by default on all machines, until an administrator is coming up to set the keys or run an installer.

Let me try summarize the problem as I see it here

The issue
We currently have an issue in that, since many windows users don't build binaries, but install them in various locations. As such build time paths are useless because there is a disconnect between where the openssl builder define these paths to be vs where the installers place the files expected to be on those paths. On that much I think we agree

The (likely) current solution
I expect most solutions in the wild ignore the build time defaults by making use of the OPENSSL_CONF/OPENSSL_ENGINES/OPENSSL_MODULES environment variables which override these defaults in most caess. For the remaining cases (mostly X509 cert store locations and CT logging), there are programatic overrides that can be made. As such, this solution only applies to applications which have ignored those overrides.

Your solution
You (I think) are proposing that we modify openssl such that, on windows, these build time defaults are replaced with a run time default, by calling SHGetSpecialFolderPath to identify a location that is both considered secure and in a known 'good' location that is discoverable at run time. This does indeed solve the problem as described above

My concern with your solution
My concerns are twofold:

  1. People deploying openssl at install time with applications in the wild aren't necessarily going to place the needed binaries/config files in the location ShGetSpecialFolderPath points to. As such, while this solution makes it possible to properly configure openssl securely on windows, it doesn't create any sort of automatic secure functionality. If someone deploying openssl places their provider files or configs in an alternate location, this doesn't help.

  2. This limits the use of openssl on windows to a single deployment. Consider the situation where two application providers, A and B, have both deployed applications with statically linked openssl libraries. In this situation, both applications will use the configs/engines/providers located in SHGetSpecialFolderPath. If both applicaitons use different versions of openssl, or more importantly, want different configurations, they can no longer do that (assuming the use of the default locations), as they both fetch that data from a shared location. Thats not reasonable.

My solution
I'm proposing (and working on), a modification to openssl which allows a built openssl library to lookup the requisite paths using registry keys of the form:
HKLM\SOFTWARE\OpenSSL-<version>-<context>
Where:
is the openssl library version set at build time
is an arbitrary string created by the builder of openssl, and reportable via the openssl version -w command

The idea being that for any application which consumes openssl, the builder may select a unique keyname using the context definition (ostensibly set to the name of the application or distribution being built), to create a unique per application key

Given that new mechanism, A system administrator, at install time, may select a file path location unique to that application and inform the embedded openssl library of that path by setting the appropriate values for OPENSSLDIR/ENGINESDIR/MODULESDIR within that key. This allows each application to select its own file path location that is considered secure by the administrator, and solves the shared space problem described in (2) above.

I grant you that, for applications without installers, there is an extra step here in that an administrator will need to set these registry keys manually (via the reg utility or some such), but at least they have option to do so. If they choose not to, well, then they are using defaults that may or may not be correct, but I don't see there being much we can do about that. This also doesn't help applications already deployed in the wild, but again, neither solution fixes deployments already out there.

My concern with your solution My concerns are twofold:

  1. People deploying openssl at install time with applications in the wild aren't necessarily going to place the needed binaries/config files in the location ShGetSpecialFolderPath points to. As such, while this solution makes it possible to properly configure openssl securely on windows, it doesn't create any sort of automatic secure functionality. If someone deploying openssl places their provider files or configs in an alternate location, this doesn't help.

The issue isn't that the configuration files are or aren't there. This situation has already been the case since the existence of OpenSSL, even in envs that matches the build-time default paths. If the config files are not there, or are elsewhere, they just weren't used. This doesn't break OpenSSL. My proposal doesn't change this behaviour. The issue is that on systems that don't match the build-time defaults, such configuration can be malicious placed by anybody on that system, because the build-time locations are world-writable.

  1. This limits the use of openssl on windows to a single deployment. Consider the situation where two application providers, A and B, have both deployed applications with statically linked openssl libraries. In this situation, both applications will use the configs/engines/providers located in SHGetSpecialFolderPath. If both applicaitons use different versions of openssl, or more importantly, want different configurations, they can no longer do that (assuming the use of the default locations), as they both fetch that data from a shared location. Thats not reasonable.

Please explain how my proposal makes this any worse than it already is? I don't understand.

Before this proposal, A and B were both looking for the configs at C:\Program Files*\. After my proposal they will both be looking for configs at the same place on a given machine, but the correct Program Files directory for that machine.

I understand what you are saying, but I don't see anything in my proposal that would make the existing situation any worse in this regard.

These are two distinct problems, and my proposal fixes the default paths. The A/B config problem can be tackled independently.

My solution I'm proposing (and working on), a modification to openssl which allows a built openssl library to lookup the requisite paths using registry keys of the form: HKLM\SOFTWARE\OpenSSL-- Where: is the openssl library version set at build time is an arbitrary string created by the builder of openssl, and reportable via the openssl version -w command

The idea being that for any application which consumes openssl, the builder may select a unique keyname using the context definition (ostensibly set to the name of the application or distribution being built), to create a unique per application key

Given that new mechanism, A system administrator, at install time, may select a file path location unique to that application and inform the embedded openssl library of that path by setting the appropriate values for OPENSSLDIR/ENGINESDIR/MODULESDIR within that key. This allows each application to select its own file path location that is considered secure by the administrator, and solves the shared space problem described in (2) above.

I grant you that, for applications without installers, there is an extra step here in that an administrator will need to set these registry keys manually (via the reg utility or some such), but at least they have option to do so. If they choose not to, well, then they are using defaults that may or may not be correct, but I don't see there being much we can do about that. This also doesn't help applications already deployed in the wild, but again, neither solution fixes deployments already out there.

In effect, it means this problem isn't solved, and a significant portion of OpenSSL uses remain insecure by default.

While this issue isn't about the means to override the default paths, IMO the #24450 solution is unnecessarily convoluted. The straightforward solution is to allow applications to set these configuration paths at runtime (on initialization) to whatever value they want. Requiring installers, install steps and using an elaborate HKLM key tree just doesn't feel "natural" and also makes any user apps non-relocatable (aka non-"portable") within the same machine.

Also a reminder that on Windows there is no mandatory installation step. It's the job of the binaries to adapt to the environment on the go.

Just to add: My proposal is just one possible solution. It came about by watching this problem for many years and wondering about it, also trying to mitigate it in my own OpenSSL builds, with a history of developing apps that run on Windows. There may be other solutions to this (a few outlined in the opening post). OpenSSL users would be served by any solution that fixes this problem by default. Emphasis on by default. Meaning an OpenSSL build for Windows must be secure on any/all Windows machines, either by not loading stuff from disk by default, or ensuring it only loads things from places which are at least as securely stored as the binaries themselves.

A good way to ensure that is to omit any hard-coded paths from the binaries (by default).

For now OpenSSL is trivially vulnerable in a significant portion of systems out there.

The no-autoload-config no-engine no-module no-dso no-shared configuration most likely fixes this, but this loses functionality so probably not practical for many users, obviously not a default configuration, and it still leaves the vulnerable hard-coded path in the binaries, making it difficult to ensure that those are never actually used. As noted above, there is no build-time --prefix/--openssldir that fixes this problem.

Security isn't an add-on feature, but a necessity IMO.

IMO a good compromise is to read the paths from the registry and NOT fall back to any built-in defaults if the registry keys aren't set. There is no point in the fallback as there aren't likely to be any useful config files/modules/certificates at the built-in default paths unless the OpenSSL is properly installed. And properly installing means the registry can be set appropriately.

Of course the no fallback change cannot be backported to stable branches.