Skip to content
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

Define a PowerShell BinaryFormatter Obsoletion Strategy #14054

Open
fMichaleczek opened this issue Nov 12, 2020 · 19 comments
Open

Define a PowerShell BinaryFormatter Obsoletion Strategy #14054

fMichaleczek opened this issue Nov 12, 2020 · 19 comments
Labels
Issue-Enhancement the issue is more of a feature request than a bug WG-Remoting PSRP issues with any transport layer

Comments

@fMichaleczek
Copy link

dotnet team has published his BinaryFormatter Obsoletion Strategy (07/23/2020)

There is already an impact for PowerShell 7.1 as ASP.NET projects disable BinaryFormatter by default (but can enable)
See #14032

The next impacts will be :

  • .NET 7 (Nov 2022) BinaryFormatter disabled by default across all project types
  • .NET 8 (Nov 2023) BinaryFormatter infrastructure removed from .NET

The documentation about BinaryFormatter security guide is published.

@fMichaleczek fMichaleczek added the Issue-Enhancement the issue is more of a feature request than a bug label Nov 12, 2020
@SteveL-MSFT SteveL-MSFT added this to the 7.2-Consider milestone Nov 12, 2020
@iSazonov iSazonov added the WG-Engine core PowerShell engine, interpreter, and runtime label Nov 13, 2020
@SteveL-MSFT SteveL-MSFT modified the milestones: 7.2-Consider, 7.3-Consider Dec 7, 2020
@SteveL-MSFT SteveL-MSFT added WG-Remoting PSRP issues with any transport layer and removed WG-Engine core PowerShell engine, interpreter, and runtime labels Mar 19, 2021
@SteveL-MSFT
Copy link
Member

BinaryFormatter is really only used by remoting for TimeZone. The only other case is the communication between Out-GridView WPF app and the cmdlet which we can update as that's an internal communication. However, the remoting change may require a rev to PSRP protocol specification and will break legacy clients although we could have a fallback strategy in the protocol.

@SteveL-MSFT
Copy link
Member

cc @PaulHigin

@jhoneill
Copy link

This seems to also hit remoting from .NET interactive, for which there doesn't appear to be a work around currently.

@awakecoding
Copy link
Contributor

@SteveL-MSFT @fMichaleczek we've recently managed to get our first .NET 6 builds of Devolutions Server, and we've encountered this issue which is fixed for now using EnableUnsafeBinaryFormatterSerialization. Can you confirm that whatever happens with the binary formatter deprecation, future versions of the PowerShell SDK will still be able to connect to older versions of PowerShell, especially for Windows PowerShell 5.1 over a WinRM transport?

@iSazonov
Copy link
Collaborator

iSazonov commented Apr 8, 2022

future versions of the PowerShell SDK will still be able to connect to older versions of PowerShell, especially for Windows PowerShell 5.1 over a WinRM transport?

As said in the BinaryFormatter Obsoletion Strategy, the code will be removed in .Net 8. Until that you can use the code with EnableUnsafeBinaryFormatterSerialization.

@awakecoding
Copy link
Contributor

future versions of the PowerShell SDK will still be able to connect to older versions of PowerShell, especially for Windows PowerShell 5.1 over a WinRM transport?

As said in the BinaryFormatter Obsoletion Strategy, the code will be removed in .Net 8. Until that you can use the code with EnableUnsafeBinaryFormatterSerialization.

Yes, but that doesn't answer the question of backward compatibility with Windows PowerShell 5.1 servers when using a future .NET 8 PowerShell SDK client. I don't know how much it relies on BinaryFormatter, but is it possible to replace just the required bits in the PowerShell SDK such that it keeps working? BinaryFormatter may be deprecated, but Windows PowerShell 5.1 will still be officially supported for years to come as it ships built-in with Windows Server

@iSazonov
Copy link
Collaborator

iSazonov commented Apr 9, 2022

Yes, but that doesn't answer the question of backward compatibility with Windows PowerShell 5.1 servers

Obviously, the distance between .Net and the .Net Framework increases with each new version and the ecosystem is obviously splitting into two parts. As for PowerShell, this split has already happened and is doubly amplified by the split in .Net, so in my opinion it is not serious to talk about forward or backward compatibility.

@awakecoding
Copy link
Contributor

awakecoding commented Apr 9, 2022

Correct me if I'm wrong, but from your answer it really looks like we're crossing fingers that by the time PowerShell uses .NET 8, Windows PowerShell 5.1 won't really be a thing anymore.

I agree with deprecating BinaryFormatter, and it makes sense to drop support for it from the .NET runtime, but we need a plan to have a working PowerShell SDK that can still connect to the still-supported Windows PowerShell 5.1 when this happens. It is going to be there for a LONG time, it's built-in to Windows Server, and Windows Server has a long lifetime before reaching its EOL.

I really don't know much about BinaryFormatter, and from Steve's previous answer, it looks like we're using it only in two places (time zones and Out-GridView). If someone could point to the source files affected maybe we could better assess ways to retain compatibility?

Another possibility would be to move the required classes in a nuget package separate from the .NET runtime that could be used in PowerShell, like Microsoft.Windows.Compatibility: https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack

Learn about the Windows Compatibility Pack and how can you use it to port existing .NET Framework code to .NET 5 and .NET Core 3.1.

@iSazonov
Copy link
Collaborator

Correct me if I'm wrong, but from your answer it really looks like we're crossing fingers that by the time PowerShell uses .NET 8, Windows PowerShell 5.1 won't really be a thing anymore.

Current MSFT PowerShell team policy is to release next pwsh in the day next .Net version is released.
If we look .Net roadmap .Net 8 is scheduled for November 2023. So 2024 is a time we lost BinaryFormatter. It is worth noting that we also lose SecurityString and more.
MSFT also officially announced that it is not worth starting projects related to .Net Framework, all new projects should be on .Net.
If you already have a project on the .Net Framework, you are doomed to struggle with incompatibilities. It will get worse every day. Moreover, .Net is based on a short lifecycle, so you will not have time to pause and respawn.

@fMichaleczek
Copy link
Author

Correct me if I'm wrong, but from your answer it really looks like we're crossing fingers that by the time PowerShell uses .NET 8, Windows PowerShell 5.1 won't really be a thing anymore.

Current MSFT PowerShell team policy is to release next pwsh in the day next .Net version is released. If we look .Net roadmap .Net 8 is scheduled for November 2023. So 2024 is a time we lost BinaryFormatter. It is worth noting that we also lose SecurityString and more. MSFT also officially announced that it is not worth starting projects related to .Net Framework, all new projects should be on .Net. If you already have a project on the .Net Framework, you are doomed to struggle with incompatibilities. It will get worse every day. Moreover, .Net is based on a short lifecycle, so you will not have time to pause and respawn.

IHMO, integrate System.Text.Json and JsonSerializer, is the first thing to do. Because it's the future and maybe the solution (clijson ?).

@awakecoding
Copy link
Contributor

I made a twitter thread about this yesterday, and @jborean93 came up with the simplest possible solution for the BinaryFormatter API obsoletion: https://twitter.com/BoreanJordan/status/1512978332887175170?t=VwkOfkZ-zt69Vj8J0TEJzA&s=19

All we really need is custom code to handle the time zone stuff during the connection sequence. It is benign in nature, and we could make a fix already such that connections work with .NET 6 without re-enabling BinaryFormatter. The real BinaryFormatter APIs are not required, Jordan was able to write custom code for the time zone stuff in his own Python implementation, there aren't that many possible combinations to handle.

As for Out-GridView, it is only really used interactively, so I suggest we should update the PowerShell server not to use it unless it is already the case, and not bother about backward compatibility since interactive PowerShell clients can reasonably switch to PowerShell 7. non-interactive use through the PowerShell SDK is what truly matters.

Should we create a separate issue to add a proper fallback for the time zone stuff in the current code base, link it to this issue? It would fix at least the current problem.

As for other planned deprecated APIs, are there issues opened for all of them, and can someone link them here so we have a good idea of other issues coming up that would break backward compatibility with Windows PowerShell servers?

@doctordns
Copy link
Contributor

A small point - I would not wish to see a "powershell server" edition as noted in the third para.

@jborean93
Copy link
Collaborator

jborean93 commented Apr 10, 2022

Looking at the code a bit further, it seems like for the SessionCapability message both the client and server exchange don't even use the TimeZone value, it just defaults to the default time zone of that host

if (dataAsPSObject.Properties[RemoteDataNameStrings.TimeZone] != null)
{
// Binary deserialization of timezone info via BinaryFormatter is unsafe,
// so don't deserialize any untrusted client data using this API.
//
// In addition, the binary data being sent by the client doesn't represent
// the client's current TimeZone unless they somehow accessed the
// StandardName and DaylightName. These properties are initialized lazily
// by the .NET Framework, and would be populated by the server with local
// values anyways.
//
// So just return the CurrentTimeZone.
#if !CORECLR // TimeZone Not In CoreCLR
result.TimeZone = TimeZone.CurrentTimeZone;
#endif
}
. This means that as a client there doesn't seem to be any consequence to omitting the value at all and they both already ignore it. Going back versions, v2 will try to deserialize this value but is fine if it is omitted. PowerShell 3 is when they removed this deserialization on the server due to what looks like security concerns so I'm fairly confident it's ok for PowerShell as a client to just stop sending that field altogether. Event when looking at what ultimately uses this data from the server it seems like it's only set for PSSenderInfo.ClientTimeZone and nothing else internally.

The other mentioned usage is with Out-GridView, this is not something I'm really knowledgeable on. I cannot even get it working on Linux after following https://devblogs.microsoft.com/powershell/out-gridview-returns/. When attempting to see what it looks like across the wire within PSRemoting not even WinPS allows it so if it uses the binary serializer in any way it should just require an update in the pwsh code and we don't need to worry about being backwards compatible for remoting sessions there

> "a" | Out-GridView
Out-GridView : Out-GridView does not work in a remote session.
At line:1 char:7
+ "a" | Out-GridView
+       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Microsoft.Power...GridViewCommand:OutGridViewCommand) [Out-GridView],
    NotSupportedException
    + FullyQualifiedErrorId : RemotingNotSupported,Microsoft.PowerShell.Commands.OutGridViewComman

I have no idea if there are any other usages of BinaryFormatter, a quick search brings up https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs but I'm not sure what it's used for, considering it's in a namespace with UI it probably is the Out-GridView stuff.

PowerShell Team
Out-GridView Returns! It’s been almost 3 years since PowerShell Core debuted for Linux and Mac, and as we’ve increased our cmdlet coverage more and more, one cmdlet has always stood out as a top, cross-platform request. Today, we are excited to announce that Out-GridView is debuting on all Core-supported platforms through the GraphicalTools Module.

@antonGritsenko
Copy link

future versions of the PowerShell SDK will still be able to connect to older versions of PowerShell, especially for Windows PowerShell 5.1 over a WinRM transport?

As said in the BinaryFormatter Obsoletion Strategy, the code will be removed in .Net 8. Until that you can use the code with EnableUnsafeBinaryFormatterSerialization.

Any idea why it may not work in Azure Functions even if EnableUnsafeBinaryFormatterSerialization is set?

@NN---
Copy link

NN--- commented Jul 13, 2022

dotnet/runtime#72132

@LeonarddeR
Copy link

As far as I know, binary formatter is supposed to be removed in .NET 8. Is this still on the radar?

@xtqqczze
Copy link
Contributor

xtqqczze commented May 2, 2023

As far as I know, binary formatter is supposed to be removed in .NET 8. Is this still on the radar?

The updated plan is for the entirety of the BinaryFormatter infrastructure to be removed in .NET 9. Functionality may be moved to an unsupported out-of-band package.

https://github.com/dotnet/designs/blob/main/accepted/2020/better-obsoletion/binaryformatter-obsoletion.md

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 16, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot removed this from the 7.2-Consider milestone Nov 23, 2023
@Balkoth
Copy link

Balkoth commented May 2, 2024

Isn't this still a problem because of: dotnet/runtime#98245

@kilasuit kilasuit reopened this May 2, 2024
@kilasuit kilasuit removed the Resolution-No Activity Issue has had no activity for 6 months or more label May 2, 2024
@xtqqczze
Copy link
Contributor

xtqqczze commented May 2, 2024

See also:
dotnet/wpf#1131
dotnet/winforms#6267

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug WG-Remoting PSRP issues with any transport layer
Projects
None yet
Development

No branches or pull requests