Skip to content

Add warning for using BinaryFormatter in GenerateResource on .NET 8 #8524

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

Merged
merged 8 commits into from
Mar 29, 2023

Conversation

Forgind
Copy link
Contributor

@Forgind Forgind commented Mar 3, 2023

It will be removed in .NET 9; doing so should be discouraged.

Note that this does nothing by default, but we can change that in the SDK.

Fixes #8453

Context

BinaryFormatter is deprecated and will be removed in .NET 9. In addition to the possibility of using a modern MSBuild with an older framework, there are apparently ways you can exempt your project, so we are not currently removing it entirely, and this warning (which is off by default) can be disabled even if it is enabled in the SDK.

Changes Made

I deleted using System.Runtime.Serialization.Formatters.Binary; in GenerateResource, then put a warning before the one usage of BinaryFormatter. That isn't necessarily the best way to figure out where it's used, as it would be helpful to know early, so feel free to comment to that effect.

Then I disabled it via a property and will make a separate PR to enable it in the 8.0 SDK.

Testing

Notes

It will be removed in .NET 9; doing so should be discouraged.

Note that this does nothing by default, but we can change that in the SDK.
@Forgind Forgind changed the title Add warning for using BinaryFormatter on .NET 8 Add warning for using BinaryFormatter in GenerateResource on .NET 8 Mar 3, 2023
// Warn of BinaryFormatter exposure (on by default in .NET 8+)
if (logWarningForBinaryFormatter)
{
log.LogWarningWithCodeFromResources("GenerateResource.BinaryFormatterUse", name, resxFilename, mimetype);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think typename is of more interest than mimetype here. The user likely didn't set the mimetype but let a tool specify that by serializing an object.

On the flip side, it's conceivable that a given object is serializable both via binaryformatter and typeconverter so a different representation of the same object wouldn't throw. Hmm. @merriemcgaw do you have a preference (or a suggestion for someone who might)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not personally, but I wonder if @JeremyKuhne and/or @ericstj might have thoughts. My first thought would be to agree typename is more interesting but you bring up an interesting case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's for developers why not include both?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MimeType here can be one of 3 values, 2 of which haven't been used since like .NET 1.0 days so its probably not all that useful except to help the user know why the resource was being flagged. Probably could be left out to make a less scary warning and just mentioned in the documentation for the diagnostic ID. Agreed that typename is much more useful.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericstj is right -- I forgot those were legacy

// Warn of BinaryFormatter exposure (on by default in .NET 8+)
if (logWarningForBinaryFormatter)
{
log.LogWarningWithCodeFromResources("GenerateResource.BinaryFormatterUse", name, resxFilename, mimetype);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check log is null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd initially intended it to just never be null, but then I broke my own invariant when tests came along and made a narrower and more confusing invariant. I'll change this.

// Warn of BinaryFormatter exposure (SDK should turn this on by default in .NET 8+)
if (logWarningForBinaryFormatter)
{
log?.LogWarningWithCodeFromResources("GenerateResource.BinaryFormatterUse", name, resxFilename, typename);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put resxFilename in location instead of in message
Try to find line number of resource using bf

Forgind added 2 commits March 6, 2023 13:45
Not fully tested, but looks promising
Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test of the end-to-end scenario showing that it fires when opted in in GenerateResource_Tests?

@@ -1161,6 +1161,11 @@
<value>MSB3824: In order to build with .NET Core, resource inputs must be in .txt or .resx format.</value>
<comment>{StrBegin="MSB3824: "}</comment>
</data>
<data name="GenerateResource.BinaryFormatterUse">
<value>MSB3825: Resource "{0}" of type "{2}" is deserialized via BinaryFormatter at runtime. BinaryFormatter is deprecated due to possible security risks and will be removed with .NET 9. If you wish to continue using it, set property "GenerateResourceWarnOnBinaryFormatterUse" to false.
More information: https://learn.microsoft.com/dotnet/standard/serialization/binaryformatter-security-guide</value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a helplink field on the warning? can we set that too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds familiar, but I'm having trouble finding what I'd expected.

Searching for "helplink" didn't return anything helpful.
Searching for "help" in the TaskLoggingHelper revealed that there's a HelpKeywordPrefix (generally just set to MSBuild) that's added to the messageResourceName, so no action there, but I don't think that's what you meant.
Searching for "help" in the same Strings.resx revealed nothing.
Searching the whole repo for <help also didn't work.

Any suggestions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We noticed that HelpLink is available, but there isn't a helper method for it yet. I suggested I'd make a follow-up PR to fix that and clean up all the other instances using it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#5493 (comment) <-- we don't actually have an easy way to do this right now. So we can wait.

@Forgind
Copy link
Contributor Author

Forgind commented Mar 7, 2023

Can you add a test of the end-to-end scenario showing that it fires when opted in in GenerateResource_Tests?

Fear not! I've been working on that all afternoon 🫡

@@ -1161,6 +1161,11 @@
<value>MSB3824: In order to build with .NET Core, resource inputs must be in .txt or .resx format.</value>
<comment>{StrBegin="MSB3824: "}</comment>
</data>
<data name="GenerateResource.BinaryFormatterUse">
<value>MSB3825: Resource "{0}" of type "{2}" is deserialized via BinaryFormatter at runtime. BinaryFormatter is deprecated due to possible security risks and will be removed with .NET 9. If you wish to continue using it, set property "GenerateResourceWarnOnBinaryFormatterUse" to false.
More information: https://learn.microsoft.com/dotnet/standard/serialization/binaryformatter-security-guide</value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#5493 (comment) <-- we don't actually have an easy way to do this right now. So we can wait.

@Forgind Forgind added merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. and removed merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. labels Mar 28, 2023
@JaynieBai JaynieBai merged commit dd5d9f7 into dotnet:main Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Warn when using BinaryFormatter resources while targeting .NET 8+
6 participants