On 3/4/2025 4:22 PM, Gavin Lambert wrote:
> I don't think I'd go that far -- just treat it with the caution it
> deserves, as a local data cache shared between all users of a PC, including
> potentially untrustworthy ones.
While it's obvious that users can freely modify and delete files under
ProgramData and break the associated app (assuming the permissions
aren't tightened), what's not as widely known is that reparse points can
be employed there to gain access to files in other users' profiles. Also
not widely known is that even though Windows' default security policy
only allows Administrators to create symbolic links, there's another
type of link known as a "pseudo-symlink" that can be created by
unprivileged users.
For example, if an app sends email as part of its operation and is known
to append the contents of "C:\ProgramData\MyApp\signature.txt" to the
messages it sends, a user could replace that file with a
(pseudo-)symlink that points to a confidential file within another
user's profile, e.g. "C:\Users\Joe\Documents\Secret.txt". When Joe logs
in and runs the app, the contents of Secret.txt will be divulged in the
emails that are sent.
If an app *really* must read or write files in a world-writable
directory like ProgramData without the user explicitly requesting it,
steps should be taken to ensure reparse points are not followed.
The simplest mitigation may be to enable "RedirectionGuard" for the
process using the SetProcessMitigationPolicy API, which should prevent
any non-admin-created reparse points from being followed. (To do: Add an
option to enable this in Inno Setup installers.) However, that might be
unsuitable for apps that need to follow legitimate symlinks a user has
created in their own profile.
Another option is to check for the FILE_ATTRIBUTE_REPARSE_POINT
attribute on files that are opened in the insecure location
(ProgramData), and on any parent directories that aren't securely ACLed.
Also pass FILE_FLAG_OPEN_REPARSE_POINT when opening the file if
possible. This method isn't perfect, though; there's a TOCTOU problem.
I still say it's best to avoid ProgramData whenever possible. If an app
has a file that needs to be editable by any user, install it under {app}
but use "Permissions: users-modify" on the file. All users will be able
to modify the file's contents, but they shouldn't be able to swap it out
with a reparse point because they don't have write access to the
directory (assuming {app} is under Program Files). So no special
precautions are needed when opening the file.
-JR