Powershell: $PROFILE on a shared folder gives security warning if remote system has periods in the name

Created on 6 Aug 2018  路  55Comments  路  Source: PowerShell/PowerShell

Tested on 6.1.0-preview.4 6.1rc, 6.1 release, and 6.2-preview.1

Steps to reproduce

1) Have your IT department force sticking your profile on a shared drive.
2) Ensure your executionpolicy is Unrestricted
2) Start pwsh

Expected behavior

My profile loads, as it does with 6.0.3

Actual behavior

```When pwsh starts up, I get the following message:
Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can
potentially harm your computer. If you trust this script, use the Unblock-File cmdlet to allow the
script to run without this warning message. Do you want to run
\Wherever\whatever$\UD3\myusername\My Documents\PowerShell\Microsoft.PowerShell_profile.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"):


If I say [R]un Once, my profile will load, but I will get the same message for every module in my profile.                                                                                                      




Environment data
----------------

$PSVersionTable

Name Value
---- -----
PSVersion 6.1.0-preview.4
PSEdition Core
GitCommitId 6.1.0-preview.4
OS Microsoft Windows 10.0.14393
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

get-executionpolicy
Unrestricted

Issue-Question

Most helpful comment

We can't rely on IE APIs. What I propose is that we add definitions of trusted remote systems in our powershell.config.json file.

All 55 comments

@weloytty Have you tried using a signed file?

No, because it's my profile and I mess with it a lot. (I have run Unblock-File $PROFILE though, since that's what the error message tells me to do, and I get the same behavior once I have done that)

I also end up with my modules folder on a UNC share too, and I get the same behavior. I could move my profile to $profile.AllUsersCurrentHost, but I'd prefer to keep the 6.0.3 behavior.

@weloytty Could you please compare the scenario with Windows PowerShell?

Windows powershell behaves the same way that pwsh 6.0.3 does, it loads my profile with no warnings

@SteveL-MSFT Could you please comment the use case? I'd expect that we could trust signed scripts at least.

@iSazonov and @weloytty I think this behavior is correct as the script is still residing in a remote location. Execution policy is always for a script which is available locally(no matter from where it is developed). Correct me if I'm wrong.

The default ExecutionPolicy is RemoteSigned and a network share is Remote so this behavior is by-design. Other than signing the script, the other solution is to change your execution policy.

@SteveL-MSFT It's by design even if my executionpolicy is Unrestricted?

`
PS C:\Users\someone> get-executionpolicy
Unrestricted
PS C:\Users\someone> .$PROFILE

Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your
computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning
message. Do you want to run \na.something.com\WLNC-UD$\UD3\someone\My
Documents\PowerShell\Microsoft.PowerShell_profile.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"):

`

Your profile script is both unblocked and executionpolicy is unrestricted? Can you try bypass execution policy?

Correct, I have run unblock-file $PROFILE and execution policy is unrestricted.
-ExecutionPolicy Bypass worked as expected (no prompt when running profile).

I've attached a transcript of what happens, starting from cmd
7548.txt

@weloytty thanks for the details, I'll see if I can repro this locally. I would suggest removing the network paths in your transcript to something generic like \\server\share as to not make internal information public

problem still exists in RTM

I also have the same problem over here with RTM version, ExecutionPolicy = Unrestricted
For every loaded module and $profile I have to confirm it and there is no option to Confirm All
I even tried adding the UNC path to Trusted Sites but no success. Any help how to solve this? I didn't have this issue with the previous version.. Many thanks

@KurtDeGreeff can you be more specific about "previous version"? It would help to know when this was changed so we can find the change that caused this. Thanks.

@SteveL-MSFT I didn't have this issue in v6.1.0-rc1 or lower

@KurtDeGreeff do you really mean rc1? the top of this issue says preview.4? I don't recall any changes we've taken in 6.1 that should affect this. Would be great if we can isolate the release where it was working as expected and when this issue was introduced.

I believe top of the issue says Preview 4 because that's when I saw it for the first time. It makes sense for @KurtDeGreeff to see the same behavior in a build that's later than the one I saw it in.

(And as an additional datapoint, I do not get the problematic behavior on 6.0.4, which also came out after I created the issue)

Behavior still occurs on 6.2p1

My duplicate #8298 may shed additional light on the expected behavior with RemoteSigned and "trusted" file shares when coming from Windows PowerShell.

My temporary workaround is: make the AD people issue me a code signing cert.

@dbaileyut your findings may help find root cause. There was an older commit to determine the security zone on Core and if the UNC share has a dot in the name (like \\foo.bar.com\share or \\1.2.3.4\share) then it is treated as internet, otherwise intranet. If intranet, the file is treated as local. In @weloytty's repro above, it appears the UNC path has periods in it, so the code thinks it's internet which causes loading to fail (unless signed). I suppose one option is to resolve the computer name to see if it's in the same subnet, but then it can get complicated and still not work for all cases.

I can confirm the UNC path without dots works as expected for me under 6.1.1.
Mapping a traditional drive letter via Explorer/ "net use" appears to be another workaround (but not creating a PSDrive using a path with dots).

My case would be one where resolving the computer name to see if it's in the same subnet would fail (unless signed, of course).

Unless someone knows of a reliable way to determine of a remote system is on the intranet, I think we may have to resolve this as a doc issue.

@SteveL-MSFT - this may be a separate issue but with commit you referenced, is there a security risk to trusting "Zone.Identifier" being less than Internet/"3" (i.e. more trusted)?

In 6.1.1, I was able to write a Zone.Identifier of "1" in a stream on my test script as non-administrator and execute it the UNC path using an IP address. On Windows Powershell, the same UNC path was rejected with RemoteSigned and the Zone.Identifier.

(Windows PowerShell also enforces the MachinePolicy from Group Policy and doesn't allow my non-administrator account to override my CurrentUser or Process as Bypass. PowerShell 6.1.1 lets me do that)

Seems like the algorithm should be reversed:

  1. The file path will be used to determine the initial SecurityZone
  2. If the alternate data stream "Zone.Identifier" is in the valid format and greater than the zone determined by the path, use SecurityZone from Zone.Identifier data stream.

That way, the alternate data stream can't be used to make the script more trusted, only less.

cc @PaulHigin @TravisEz13 to review security implications

Unless someone knows of a reliable way to determine of a remote system is on the intranet, I think we may have to resolve this as a doc issue.

The best I can imagine is resolving the name and comparing to the RFC 1918 subnets and considering all of them intranet but that's probably too broad.

I agree with the change suggested here, https://github.com/PowerShell/PowerShell/issues/7458#issuecomment-440108767, with a caveat. I believe this more closely matches the Windows PowerShell and IE behavior.

The Execution Policy feature helps prevent users (as opposed to automation) from executing untrusted code, but it uses imperfect means.

  1. Dots in the name or the lack there of is not a perfect indication is the host is an internet or intranet host (you can fully qualify an intranet address or add an internet domain to your search list).
  2. As others have mentioned, the alternate data stream can be tampered with (PowerShell has the unblock-file cmdlet).
  3. As far as subnet numbering RFCs, yes private subnets are intranets, but you also may be connected to a random hotspot which should not be trusted.
  4. Finally, it is not designed to stop users or automation that is trying to bypass the policy.

I wonder how we could port this?

@TravisEz13 The code doesn't currently work on Unix. Is it important to have it working on Unix too?

@iSazonov the concept doesn't exist on Unix, so it only needs to work on Windows

I've worked around this by creating a code signing certificate of my own. (I am still trying to get my IT to sign the key I made (or give me one of my own), but It's fun trying to explain to the help desk what a code signing certificate is). I don't think this is a very good solution, but it works ok.

(The instructions from @shanselman at https://www.hanselman.com/blog/SigningPowerShellScripts.aspx were invaluable)

For what it's worth, I have a similar issue with PowerShell on Windows Server 2019 Core, and could resolve it by setting a Group Policy with two Intranet Sites settings: Include all local (intranet) sites not listed in other zones" and "Intranet Sites: Include all network paths (UNCs)".

I reply here, instead of making a new bug report, because it might shed some light on this issue and may help others (in either resolving their issue, or in resolving this bug).

PS C:\Windows\system32> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17763.134
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.134
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

I couldn't run .ps1 files that are on a network share (v:). It had nothing to do with dots in the name, as the share is created using a short DNS CNAME: \\deployment.

When trying to run v:\servername.ps1 (which should output the computer name using Write-Host ${env:computername}), I get:

PS C:\Windows\system32> V:\servername.ps1

Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can
potentially harm your computer. If you trust this script, use the Unblock-File cmdlet to allow the
 script to run without this warning message. Do you want to run V:\servername.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"):

After reading this bug, bug #8298 and doing some testing, I found I had to add a GPO in my environment, with these two settings enabled:

After gpupdate and a reboot, which is required strangely, I can now execute my scripts hosted on a share.

I am trying out PS v7 (from PS v5.1), and just ran across this problem #7458, as well as a similar problem #8298. Please let me know if a new issue should be created for this since this is now is PS v7 (and not PS v6 as referenced in #7458 and #8298).

Even though the FQDN server name from where the files are being run from is explicitly added to the Local Intranet zone, scripts are not allowed to run the FQDN server name. Per the about_Execution_Policies for PS v7 documentation, if the Execution Policy is set to Unrestricted it:

Warns the user before running scripts and configuration files that are not from the local intranet zone

Since the FQDN server name is explicitly added into the Local Intranet zone, I expected that PS v7 would allow scripts to run from this FQDN Local Intranet location, as it did in PS v5.1.

This also means that for environments where folder redirection is used where the Documents folder is redirected to a FQDN path, PS v7's $Profile script is affected by this also each time PS 7 starts.

From the previous comment, it appears that enabling the following settings worked:

  • Intranet Sites: Include all local (intranet) sites not listed in other zones
  • Intranet Sites: Include all network paths (UNCs)" helped

However, this was already set for me, and this problem persists in PS v7. Here are my current settings:

image

I can confirm that setting the ExecutionPolicy to Bypass does not experience this problem.

Note that while signing may be an option for general scenarios, we have users who develop scripts from within their Documents folder (redirected to a FQDN server path so it is backed up), and we need to account for these types of scenarios too.

My goal is to not allow scripts to run from anywhere (ExecutionPolicy=Bypass), but rather only from trusted locations that have been specified in the Local Intranet zone (ExecutionPolicy=Unrestricted). This will be needed before we can deploy out PS v7 to our environment. How can we configure this in PS v7?

Thanks!

Please let me know if a new issue should be created

We can continue in the issue.

Perhaps @TravisEz13 or @PaulHigin could comment the issue and previous post taking into account Unix scenarios too.

This behavior is by design unless execution policy is bypass.
I believe we could have a feature request, but I think on windows, we should just use the Group Policies.

Only on linux could I see building something custom.

So to clarify, on a Windows setup it would be expected that admins would set the Execution Policies to be "bypass" to allow execution of scripts, like the PS profile, load from their FQDN Documents path, or from the Netlogon folder from our domain using the FQDN path?

From a security perspective that approach doesn't seem to offer a middle ground where IT admins still don't want scripts to run by default if run from untrusted locations, but locations that are trusted using the Local Intranet zone (or some other mechanism that PS 7 could offer if the Local Intranet zone isn't preferred anymore for some reason), would help significantly.

I suspect most modern environments use FQDN paths, so I assume this will impact many environments.

Can you help me understand why the sites in the Local Intranet zone are no longer being used/referenced when in Unrestricted mode? Note that I still expect the default Restricted mode to not allow paths from FQDN paths, even if they are in the Local Intranet zone.

In PS7, what is the difference between Unrestricted mode and Bypass mode when it comes to FQDN paths (since the PS7 documentation on this doesn't appear to be accurate)?

Thanks!

@aakash-shah,

  • Unrestricted: still checks if a file is local or remote, include if it was downloaded from the internet or comes from a remote server.
  • Bypass: no execution policy checks

The local or remote check

Windows PowerShell

In Windows PowerShell we called asking Internet Explorer directly, which caused compatibility issues, even on Windows as Internet explorer doesn't exist on all editions of windows. There was fall back code for the case when we could detect that internet explorer binaries were not present, unfortunately on some editions, the binaries would exist but this functionality would not be present.

PowerShell Core

The API Windows PowerShell is using is not a supported API and PowerShell Core is not allowed to call it.
The call was removed and the fall back code was made the primary code path. See https://github.com/PowerShell/PowerShell/pull/7103
The new primary code path reads the alternative stream to determine the zone of a file (if set by Internet Explorer or Edge), but only used the dot heuristic for determining if a host is local or remote.
The documentation is correct, it is just not using internet explorer to determine the zone of the host.

@TravisEz13: I appreciate the additional information and insight! That clears up why IE isn't being referenced anymore in PS Core aka PS v7.

Can we enhance the code to determine the zone of a host? For instance, at a minimum, could the system domain membership's FQDN domain path be considered "local" or "trusted"? That would cover at least the domain's Netlogon folder on the domain's FQDN path. Is there some other mechanism where we can inject using "trusted locations" that we used to be able to do via IE's Local Intranet zone? We'll need a way to add paths via Group Policy on Windows too. Ideally we'd like to avoid setting all of our systems to "Bypass" since that seems more open than we'd prefer, and would like to be able to specify specific trusted folders where it does not present the additional security prompt. This would help domain administrators from a security perspective too.

Thanks!

@aakash-shah Are the systems you referring to servers (where scripts are expected to run unattended) or user machines (where a user runs a script manually)?

What do you think these new features would do for you?

@TravisEz13

Are the systems you referring to servers (where scripts are expected to run unattended) or user machines (where a user runs a script manually)?

These are primarily user machines, but I will also need to address this on some Remote Desktop Servers. For the user machines, we have users who use PowerShell for development, quick tasks, etc.

While many of the PowerShell users are IT users, we are also now seeing some end users who have expressed interest in scripting tools, like PowerShell, to help perform tasks.

My end goal is to eventually install PowerShell v7 in our environment. For us to do this though, I need to ensure that users have a way to continue to do things that they did in PowerShell v5.1. As one of the IT admins, I'd like to still make it harder for my users to run a script from any random UNC path. But I would like them to be able to run scripts from their Documents folder, as well as have a PowerShell profile that works as it did before where it doesn't present a security warning. Note that our Documents (and Desktop) folders are redirected to a FQDN UNC path using the "Folder Redirection" in Active Directory/Windows environments.

What do you think these new features would do for you?

Having the ability to "trust" specific UNC paths would allow me to designate specific FQDN UNC paths for my end users. With this, I can ExecutionPolicy=Unrestricted to allow my end users to continue to set and use PowerShell profiles for their user account without any warnings, and continue to allow them to run their own scripts from their Documents folders if they choose to.

Please let me know if I wasn't clear about anything, or if I didn't address your question.

Thanks!

It seems some non-MSFT applications utilize the IE feature. Perhaps there is a public api?

Another thing to note is that the zones can be queried via the registry from the following locations:

Computer: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains

Computer Group Policy Set: HKLM\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey

User: HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains

User Group Policy Set: HKCU\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey

Values set to 1 indicate a Local Intranet zone.

So even if the IE API can't be used, these registry locations can be queried to calculate sites in the Local Intranet zone.

Perhaps this may be easier to reference versus trying to build out a new mechanism to store trusted locations.

Thanks!

@aakash-shah You referenced IE regkeys for non-enhanced protection mode.

I'd like to still make it harder for my users to run a script from any random UNC path.

Why do you want to make it harder to run from a random UNC path. Please include some reason for this. This seems arbitrary and cruel to your users. I really need to understand your reasoning to make sure attempting to fix this make sense.

Update:

Actually, that statement shows enough of your reasoning. You want to make it harder. Let's accept this as your goal and move on.

Another thing to note is that the zones can be queried via the registry from the following locations:

Implementing our own algorithm to parse the registry keys would likely introduce a very large number of bugs, when we have one now.

It seems some non-MSFT applications utilize the IE feature. Perhaps there is a public api?

This still ignores the fact that IE will not ship on many editions of windows going forward.

If we need this feature, let's design it for compatibility. Not so we have to rewrite it in 7.2.

It seems some non-MSFT applications utilize the IE feature. Perhaps there is a public api?

This still ignores the fact that IE will not ship on many editions of windows going forward.

If we need this feature, let's design it for compatibility. Not so we have to rewrite it in 7.2.

I may be assuming incorrectly here, but even if IE isn't installed, Windows still references and uses these settings for Windows Explorer. For instance if you open a file from a FQDN path, and that path is not in the Local Intranet zone, it gives you some extra warnings when opening Office files. After we add the Windows domain FQDN paths to the Local Intranet zone, it corrects that problem, and files from the FQDN UNC paths open as expected in Windows Explorer with no warnings. I haven't tested removing IE, but I assume this will need to continue to work since even though the Local Intranet settings are accessible from within IE, they apply in other areas of Windows too.

If my understanding is incorrect about this changing when IE is removed, please let me know.

Thanks!

We can't rely on IE APIs. What I propose is that we add definitions of trusted remote systems in our powershell.config.json file.

I agree with @SteveL-MSFT . We can add it to the powershell.config.json. Have PowerShell wildcard support. This is design uses existing code that would be less likely to have new bugs.

We can't rely on IE APIs. What I propose is that we add definitions of trusted remote systems in our powershell.config.json file.

@SteveL-MSFT , @TravisEz13 Can we use Group Policy to add trusted remote systems into the powershell.config.json file? If not available today, can support for this be added so that IT admins have a way to easily add support for this in our environments? Group Policy support will help IT admins significantly, and help improve adoption of PSv7.

So that I understand this better, would these trusted remote systems be defined using the DNS name only, or would we also need to specify the entire path? For instance, would we define "server.domainname.com", or would we define something like "\server.domainname.com\users*\Documents\PowerShell"? If this is already documented somewhere, feel free to point me to it.

Thanks!

I'd suggest that someone file a new feature request so that we can start with a clean issue that we can discuss the merits of this proposal.

Title: Add ability to configure internet zone server names for execution policy

Summary of the new feature/enhancement

Background

Currently the policies assume that if there is a . in the name it is internet.
This feature is needed to warn users if they are leaving the internet zone unintentionally.

Goal

The goal would be allow the PowerShell Administrators to configure what hosts are safe and will not trigger a warning by execution policy.

Proposed technical implementation details (optional)

Note: On Windows powershell.config.json can already be configured via Group Policy. See PowerShell Policy

@TravisEz13 @SteveL-MSFT Thank you very much for your time in reviewing this thread and replying to my comments/questions! As requested, I've created #12336. Please let me know if there is anything else I should add.

Thanks!

@aakash-shah You referenced IE regkeys for non-enhanced protection mode.

@iSazonov Yes you are correct! I missed the IE ESC keys under [HKLM | HKCU]\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains. Thanks for pointing that out!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SteveL-MSFT picture SteveL-MSFT  路  3Comments

andschwa picture andschwa  路  3Comments

manofspirit picture manofspirit  路  3Comments

abock picture abock  路  3Comments

aragula12 picture aragula12  路  3Comments