ironSource/node-regedit

REG_EXPAND_SZ values are expanded in SYSTEM user's context

CherryDT opened this issue · 4 comments

I found an issue which is unfortunately not easy to fix (research told me that with WMI it is actually impossible to fix). I still want to point it out. It is actually a duplicate of #6 but that issue was closed due to inactivity without further analysis.

When reading a REG_EXPAND_SZ value, I would expect it to be expanded with the current process' environment variables. For example, when reading the value Desktop from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, whose raw value is %USERPROFILE%\Desktop, I would expect to get C:\Users\david\Desktop in my case.

Unfortunately, the string is expanded by the WMI service in its own context, using the environment variables of the service's process which runs under the SYSTEM account. This leads to unexpected behavior because in my example above I get C:\WINDOWS\system32\config\systemprofile\Desktop returned (which doesn't even exist because the system account doesn't need a desktop).

As a very dirty workaround, I currently check whether a value I read is of type REG_EXPAND_SZ and if it is, I do a .replace(process.env.SYSTEMROOT + '\\system32\\config\\systemprofile', process.env.USERPROFILE) on it and cross my fingers - this works because most of the expandable registry strings I'll encounter will have something to do with a user profile path, and luckily variables like LOCALAPPDATA exist for the system account too, just as C:\WINDOWS\system32\config\systemprofile\AppData\Local et al. so replacing the profile path part works.

This issue seems to be impossible to fix - the straight-forward strategy of reading the raw value and manually replacing the environment variables is not doable because WMI expands the string even when GetStringValue (and not GetExpandedStringValue) is used, for some reason, which makes it impossible to obtain the raw value before it is expanded.

The only possible way I could think of is to use WScript.Shell's RegRead method (which has different semantics unfortunately, and where 32-bit/64-bit translation issues must be taken care of manually) for REG_EXPAND_SZ because this method does not expand the string, so it can be fetched in its raw format, and then environment variables could be replaced manually (or not at all, maybe with an option).

@CherryDT TYVM for the investigation. I will go deeper on this during the upcoming weekend

@nhz-io any news here?

This problem is now addressed with listUnexpandedValues