PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
45.59k stars 7.31k forks source link

Add ability to configure internet zone server names for execution policy in PS v7 #12336

Open aakash-shah opened 4 years ago

aakash-shah commented 4 years ago

Summary of the new feature/enhancement

Background

Currently the PowerShell policies assume that if there is a "." (period) in a PowerShell script's path, that it is in the internet zone. This presents the user with a warning when running PowerShell scripts are from a FQDN path (like \\server.domain.com).

In PowerShell versions up to v5.1, Windows Domain Administrators could define specific domains to be added to the Local Intranet Zone. Once added, PowerShell would then "trust" these paths when the ExecutionPolicy=Unrestricted and not present the user a security warning for each script that is run from these trusted paths.

7458 revealed that PowerShell Core (v6 and v7) intentionally removed the legacy IE API that was previously used to check the Local Intranet zones, and was replaced to check for just "." (periods). As per @TravisEz13 in #7458 I am creating this new feature request to discuss and address this problem.

Impact Of Changes Made In PowerShell Core

Many Windows environments use a feature called Folder Redirection such that the user's "Documents" folder is "redirected" to a server (so it appears to the user that their Documents folder is on their computer, but it really lives on the server). Many environments that use folder redirection redirect to a FQDN UNC path like \\server.domain.com\Users\username\Documents. Since these paths contain "." (periods), any script run from the user's Documents folder is presented with the PowerShell Security warning. This warning message also appears if the user has a PowerShell profile and starts PSv7, which presents this message each time:

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 \\server.domain.com\Users\username\Documents\PowerShell\Microsoft.PowerShell_profile.ps1? [D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"):

So in any environment where either Folder Redirection is being used to a FQDN UNC path, or if the environment presents users their User/Department folders on a FQDN UNC path, this will trigger security warnings and will present problems to the end user if they try to run scripts from these locations. (At this time, we cannot deploy PowerShell v7 in our environment due to this problem).

Additional details about the problem and the discussion are available in #7458.

Goal

Allow Windows Domain Administrators to configure what FQDN hosts are safe and not trigger a warning when using the Unrestricted execution policy. This would allow Windows Domain Administrators to set up PowerShell v7 so that users are still presented the security warning when running scripts from untrusted paths, but do not trigger this security warning when scripts are run from trusted paths when the ExecutionPolicy is set to Unrestricted.

Windows Domain Administrators will also need the ability to add trusted/safe hosts via the PowerShell Core Group Policies to help deploy these trusted hosts to all domain computers.

While the ability to trust FQDN hosts would solve the immediate problem and is the main problem I am hoping to have addressed, it would also be helpful if PowerShell administrators had the flexibility to not just add FQDN hosts (and all shares/files on it), but also specify paths with subfolders and wildcards. So for instance PowerShell Administrators could either choose to trust a FQDN host like server.domain.com, but also have the flexibility to trust a path like \\server.domain.com\Users\\Documents\PowerShell\.

Proposed technical implementation details

@SteveL-MSFT and @TravisEz13 suggested the following proposal to help address this problem in #7458:

A list of allowed host filters, that allow PowerShell Wildcards in the powershell.config.json.

And thank you for your time with this!

iSazonov commented 4 years ago

We could expand this on Unix too - we can detect that a path is on remote system.

TravisEz13 commented 4 years ago

@iSazonov There are no Execution policies on Unix. Let's not add scope creep to this.

iSazonov commented 4 years ago

What would be right design?

  1. All files are untrusted by default
  2. Auto detect trusted files
  3. Get trusted patterns from config file/GPO

Auto detect trusted files

Curently it is only "not have dot in folder path".

Proposal:

aakash-shah commented 4 years ago

files only current user accessible by permissions. It is folder redirection scenario. If untrusted user has an write access to a file we can not trust the file.

To provide some context, in our environment our user folder permissions are set up as follows:

I mention this to clarify that while in practical terms only the end user has access to the user's folder, and no other regular users have access to the user's folder, technically, the file server administrators are visible in the ACLs of the folder in case your proposal is querying the ACLs of the file.

In our scenario, we would still need to trust folders that may exist outside of redirected folders too, so we will likely use option 3 from above (Get trusted patterns from config file/GPO) and hence may not need this, but another way to address redirected folders is to consider trusting the locations of the known SpecialFolders Documents and Desktop. There is also the issue though when querying "[Environment]::GetFolderPath("MyDocuments")" on a system that has AppLocker since PowerShell runs in Constrained Language Mode and hence is unable to run this code to identify the path Documents folder path. But if PS can still query that somehow and trust it, that could be an option too.

iSazonov commented 4 years ago

We can have trusted defaults for ACL. The same is for well-know folders.

TravisEz13 commented 4 years ago

@iSazonov This feature is scoped to discovering host names zones. Please stay on topic. There is no change requested to how files work. Execution Policy has never considered ACLs. We are not expanding execution policy functionality. We are only restoring functionality that was lost in the port to PowerShell Core.

TravisEz13 commented 4 years ago

MyDocuments can be modified by the user (assuming it is not controlled by group policy) and would defeat the purpose of this feature. It would also be a much more limited feature and querying this does not work on all editions of windows.

TravisEz13 commented 4 years ago

If we don't trust the server, we cannot trust the ACLs on the server so they would be an unreliable way of verifying the server.

iSazonov commented 4 years ago

@TravisEz13 I wonder why you ask to limit the feature to the outdated behavior.

If we don't trust the server, we cannot trust the ACLs on the server so they would be an unreliable way of verifying the server.

We do not do a security feature like RDP NLA or TLS. Path wild cards do not allow this too. We have no need to identify a server. We can do only "measure a trust level".

TravisEz13 commented 4 years ago

@iSazonov This is a different feature than requested and out of scope. Please file a new issue if this is what your would like to discuss as this is a much longer discussion. I will keep marking this like of discussion as off topic as it will only delay this request simple request.

TravisEz13 commented 4 years ago

Broad implementation plan:

  1. add a new configuration array with a list of servers to ScriptExecution : https://github.com/PowerShell/PowerShell/blob/0c695376b748bf91447e8baf0016f0d5875e23e2/src/System.Management.Automation/engine/PSConfiguration.cs#L670

  2. Implement the logic to read it and return true if it is in the list here: https://github.com/PowerShell/PowerShell/blob/b0daa1e724cbba5e00f118001f1105bb44d91952/src/System.Management.Automation/utils/ClrFacade.cs#L204

Reference:

aakash-shah commented 3 years ago

Hello! Is there by any chance an ETA on when this is planned to be implemented?

Thanks!

SteveL-MSFT commented 3 years ago

@aakash-shah this is not something we're planning on implementing in the near term. We would accept a community contribution that implements this, however. Travis has already provided pointers to where the code should exist.

aakash-shah commented 3 years ago

Thank you for the reply. I'm unfortunately not familiar enough to know how to implement and contribute this.

We are interested in deploying PowerShell 7 to our environment but unfortunately this problem is preventing us from doing so.

If I may ask: if you had to guess (and I understand this is just a guess), do you think this is likely to be implemented in the next 12 months, or do you think it will be longer based on the other items your team is working on?

Thanks for your time!

SteveL-MSFT commented 3 years ago

This issue is current in the future milestone which means we believe it's important enough for us to fix eventually. However, I can't say when we'll get around to this.

CastyMcBoozer commented 2 years ago

This is a pretty bad usability issue, it is definitely preventing us from implementing PowerShell 7 in our environment.

TravisEz13 commented 2 years ago

@CastyMcBoozer, how is this preventing you from implementing PowerShell 7?

MisterSausage commented 2 years ago

@TravisEz13 This is also blocking our deployment of PowerShell 7. Unfortunately, being unable to run scripts from trusted network shares (specified by a UNC path with a FQDN) is a deal-breaker. I don't think this is an unusual scenario in enterprise networks, which have a tendency to become a morass of interconnected networks and remote connections over time, despite everyone's best intentions.

Proposal to fix this issue

In my opinion, the only reasonable way to restore expected behaviour is to revert to using urlmon (IInternetSecurityManager::MapUrlToZone or IInternetSecurityManager::ProcessUrlAction), like Windows PowerShell and early versions of PowerShell 6 do. This has been described here as a 'legacy IE API', but in practice it isn't - it's part of the operating system1.

Explorer (as in the shell, not IE) uses it, and Chromium uses it (and therefore, presumably, both Microsoft Edge and Google Chrome), to name just two prominent examples.

I've just double-checked to be certain, and the API continues to be available in both Windows 11 and core installations of Windows Server 2022, including when IE is removed.

I'm happy to put my time where my mouth is and submit a PR to fix this myself, but to be blunt I'm seeing hints of this being a religious issue to some contributors. If I did the work, would it be dismissed out of hand?


[1] : I think this comes from the API's provenance and location in the Microsoft Docs tree. I believe it first appeared in one of those platform-update-by-the-back-door releases of Internet Explorer in the late 90s / early 2000s.

TravisEz13 commented 2 years ago

How is this preventing you from running scripts from trusted shares?

Either sign them, or if this is automation, disable Execution Policy.

MisterSausage commented 2 years ago

@TravisEz13 The rationale is discussed in the first message in this issue, in the other issues referenced in that message, and elsewhere.

Given that:

  1. This issue is Windows-only.
  2. The solution proposed earlier in this issue involves a fair amount of work and new configuration options (that may be troublesome for enterprises to deploy universally).
  3. It's been marked as Up-for-Grabs for over a year, this particular issue was created over two years ago, and it's been discussed elsewhere for over four years, without any movement towards implementing a practical solution.

My point is that the best way to resolve this and restore expected behaviour is to use the existing API, since it's not actually going away with IE as previously assumed.

This will have multiple benefits:

  1. It won't require a lot of effort to implement.
  2. It'll prevent the need for new options, code and complexity for users that only serve to reproduce documented functionality the OS already makes available.
  3. PowerShell 7's behaviour will instantly be in accordance with Windows PowerShell, including taking account of Group Policy set up by admins for just this scenario.

I also offered to do the work myself so that this problem can be resolved once and for all.

(Sorry for the delay in response - for some reason I didn't receive a notification.)

kilasuit commented 2 years ago

@MisterSausage This repo is very accepting of PR's so if you are willing to do the work then please do go ahead and raise a PR for this to be reviewed and eventually accepted and as one of the many Working Group members as well as long time users & trainers of PowerShell I would be more than willing to support a PR if one were to be made 🙂 & if you are willing to do the work I can look to assign this issue to you too!

MisterSausage commented 2 years ago

@kilasuit Thanks Ryan. Yes, please assign it to me if you can, and I'll get it sorted in the next week or so.

kilasuit commented 2 years ago

Brilliant, I have assigned this to you and will look forward to seeing the resulting PR when it comes around!

voytas75 commented 1 year ago

Hey, any news on this topic?

viceice commented 9 months ago

that's really sad. 😞 please reopen. requirements are still preset

MickaelRoy commented 4 months ago

@MisterSausage Hi, are you able to manage this ? as this issue is open since 4 years ?

Can we provide any help to go forward ?

msftrncs commented 4 months ago

For reference: https://gist.github.com/VimalShekar/c781ed8a9d638270b88634ad3eaada72

Gist
Instantiating IInternetSecurityManager interface in PowerShell
Instantiating IInternetSecurityManager interface in PowerShell - gist:c781ed8a9d638270b88634ad3eaada72