New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support sudo <PowerShell cmdlet> 2 #11343
Comments
@SteveL-MSFT @joeyaiello My current conclusion is that we have only single way to implement cross-planform sudo - using PowerShell remoting like @anmenaga implemented Windows Compatibility. |
This has been discussed on and off. There are a few thoughts that I haven't seen in the other thread. Since that one is focused more on the UX, I'll do the dump on implementation here. Basically because PowerShell runs everything except for native commands in-process, this is very tricky. There are essentially two options, both with significant drawbacks.
Given the two options, I really don't like either of them, but certainly think (2) is the more flawed and should be excluded at the outset. This is just a braindump off the top of my head, so feel free to share, expand on or poke holes in implementation ideas here. |
@rjmholt If you continue your thinking you will finish on a kind (JEA?) of "PowerShell remoting" as implementation like me.
|
Yeah I think we agree that the best path would be an implementation using a kind of “remoting as security boundary” architecture. The part I don’t like about it is the lifetime of the elevated session. If we spin a new one up every time, it could be terribly slow. If we keep one open indefinitely, it leaves open a large attack surface. Anyway, @JamesWTruher @PaulHigin @SteveL-MSFT might have thoughts here |
Yes, it is the same as "ForEach -Parallel" - it is slow for inappropriate scenarios but works great for target scenarios. |
Sounds like we want |
Sudo implementations in the wild resolve this by spawing a new hidden process, then using the AttachConsole Api to attach the elevated process to the non-elevated caller. Check Luke Sampson's sudo.ps1 implementation. This doesnt work if you want to redirect StdIn/StdOut. So on my own implementation gsudo (windows-only) I did a workaround for this scenario capturing StdIn/Out/Err and streaming via RPC to the non-elevated instance (when redirected, as in 'gsudo dir > somefile'. |
Looks like @gerardog is willing to contribute his code to a cmdlet in PowerShell (for Windows). We should discuss the cmdlet design first. I'm ok with a |
I'd go for something like |
Is there any thought of an additional common parameter to elevate a cmdlet instead of a specific cmdlet that does it? |
The hidden elevated helper process should allow getting a close as possible to 'same UX on all platforms', shouldn't it? |
We definitely want pipeline support and also between cmdlets and native tools to work as expected. We could add a |
sudo scenario assumes executing "a whole job". So I guess the serialization may not be a problem because we must send/receive only data but not elevated methods . Thinking about security I believe PSSudo implemented by remoting should allow only to connect to local endpoint. (In the case we could use binary serialization for data) |
This looks very cool to me, but I am unclear as to what the design will be. Will it be based on remoting or @gerardog spawning a new process? Should we have an RFC to discuss? I would prefer not using remoting since it adds overhead. The serialization system can be used outside of remoting. Also I don't like the idea of using Invoke-Command since it has so many parameter sets already. I would prefer a new cmdlet like 'Invoke-AsElevated'. I am more concerned than @SteveL-MSFT about returning deserialized PSObjects, and I think it may trip up a lot of users, e.g., psudo Get-Process "pwsh" | Foreach-Object { $_.Kill() } |
I agree that this is very nice, but I'm trying to wrap my head around a cmdlet implementation. Would there be an issue with a cmdlet using dotnet core (rather than 4.7.1) due to the "can't attach to the console" notes above, or would that just dictate the specific implementation. |
Perhaps we could find how implement "process fork" version on both platforms but it causes huge problems. 1. It is double work. 2. It is obviously impossible to get the same behavior on all platforms and as result 3. we will get many negative feedbacks (bug issues). If we look .Net Core team experience they re-write some native code things on C# get same behavior on all platforms (ex., libcurl history).
pssudo should accept a script block and execute it elevated. |
Yes, we need double implementations (unless the double code is moved to .Net Core): On Unix/Linux
On Windows:
That being said, starting the elevated session will be interactive (either text or UAC), so I wonder how people will be using elevation on scripts and handle the 'interactive step'. Probably providing an easy way to fail fast if the user refuses to elevate would be a good idea:
I think Microsoft should update us here on a list of what is acceptable or not to do from a security compliance perspective. That is required to define the user experience specs first. The technical challenges should be addressed later (e.g. if we hypothetically can't launch an elevated process in the current console we can do a workaround to attach the non-elevated into the elevated one). This team can probably get help from other MS teams to find new ways to overcome those limitations. |
I want to point you towards this: KB4480116 introduced this limitation only for powershell, 3rd party libraries are not affected, therefore I'd say we should just undo that KB. |
I spent some time reading through the various links. This is great investigatory work. AFAIK there is no way to bypass UAC other than disabling it system wide, so for Windows this will have to be part of the experience. I don't immediately see a security issue with passing an elevated console through the un-elevated console, when it is the same user only elevated. Only admin users can elevate. I don't know about supporting a RunAs option, where alternate credentials would be passed in, and could be a security concern. But in any case a full security review would have to be done on the final design. At this point, I think an RFC document should be created that outlines the feature, user experience and different design approaches. |
Worth noting that UAC can prompt for credentials depending on how UAC: Behavior of the elevation prompt for standard users is configured. It's pretty common to be configured as something other than "Automatically deny elevation requests". |
I don't see a problem by attaching an elevated command prompt to an non elevated one in general. Also the UAC is not a security feature. There are multiple ways to bypass it in a network. Even without credential delegation.
Or simpler using a non standard winrm client to connect via loopback to it, as mentioned in one of the links I attached earlier. Also another thing to consider: If there are two persons, one with a limited user account and the other with an administrative one, why should the 2nd person enter his credentials into a non trusted session of the first one? This is the only case where detaching the terminal really would change anything, but the 1st user could as well just intercept the keyboard using a hardware accessory. of topic: He has physical access and regarding Microsoft security concepts it is game over, he could even get System rights by just applying windows updates, even if bitlocker disk encryption is on, yes that vulnerability is publicly known and Microsoft refused to patch it... back to topic what are possible threads: Now see how unix systems handle these threads:
What was uac designed for regarding enterprises? I'd be totally fine with the attach to unprivileged process solution, as it provides the same guarantee uac currently does, but also for comandline applications. Also it is a feature that could be made to be disableable, like uac. But anyway, we do not need to start from scratch for the security part, there is already something similar that we can hook onto its called UIAccess Applications: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop
|
So, how does this enable us to elevate a running powershell session? Thought. Is their a command we can run (such as "Powershell /elevated /no-new-window) that would allow us to do the *nix command su root to start an elevated sub-session?
|
Reading about UAC elevating the current shell, what about creating a new subshell, elevating that shell, running the specified command, then exiting that shell. |
@minecraftchest1 UAC doesn't allow you to pass input into the new shell. You could only spawn a new window. Or alternatively you would need to go through e.g. IPC to let both processes talk to each other. It's not as simple as "just spawning" another shell.
It won't, I was talking about why UAC is NOT a security boundary and related security concerns... |
So no matter how it gets done, it will require a modification to windows to do it cleanly?
|
@minecraftchest1 The cleanest implementation would be an addition to windows internals it self. It would provide the most standardized way of handling this especially because this is a core functionality that not only PowerShell is looking for. But that said there are different ways to implement it.
Edit:
For the 1st one we could just use:
For the 2nd one we would have to do a bit more advanced handling:
|
I understand. I shared this with the ReactOS project to ask what they could do. I personally don't have the patience to do things like this. |
I perfer to open UAC popup on Windows personally, just like the installers.
|
Hi! just wanted to let you know that It runs a Example usage from the docs.
(The cmdlet is optional, you can still just prepend Sorry if I am spamming this thread. I thought that mentioning it here once was on-topic. My apologies if it's not. |
Summary of the new feature/enhancement
Summarize #3232 to get working in the same way on all platforms:
sudo Remove-Item foo.txt
where foo.txt is owned by rootSee also
We have two common scenario for sudo - run a native command and run a script.
This can be easily implemented like:
Side effect on Windows: new window will be opened because:
.Net Core (and I guess Windows API too) doesn't allow to run new process attached to the same console.
So we can not get elevated
Start-Process pwsh -NoNewWindow -Credential $cred
2.1. We could implement this as for native command:
2.2. We could implement this in most power way using PowerShell remoting:
Current implementation proposal is 2.2.
Alternative proposal - start another pwsh process
Proposed name
Proposed UX behavior
It is still not clear:
The text was updated successfully, but these errors were encountered: