防止设计时业务数据泄露
Posted: Sat Jan 25, 2025 9:26 am
在开发自定义控件或从 派生的业务控制逻辑类时 UserControl,通常使用属性来管理其行为和外观。然而,如果在设计时无意中设置了这些属性,就会出现一个常见问题。这通常是因为在设计阶段没有适当的机制来防范此类情况。
设计器中典型业务线用户控件的屏幕截图
如果未正确配置这些属性以控制其代码序列化行为,则设计时设置的敏感数据可能会无意中泄漏到生成的代码中。此类泄漏可能导致:
源代码中暴露的敏感数据可能会发布在 GitHub 等平台上。
设计时数据被嵌入到资源文件中,可能是因为缺少相关属性类型所需的 TypeConverters,或者是因为表单已本地化。
这两种情况都会对应用程序的完整性和安全性造成重大风险。
此外,我们力求尽可能避免资源序列化。在 .NET 9 中, 由于安全性和可维护性问题,二进制格式化程序和相关 API 已被淘汰。这使得仔细控制序列化哪些数据以及如何序列化变得更加重要。
二进制格式化程序过去用于序列化对象,但它存在许多安全漏洞,因此不适合现代应用程序。在 .NET 9 中,我们完全消除了这个序列化程序,以减少攻击面并提高应用程序的可靠性。任何对资源序列化的依赖都有可能再次引入这些风险,因此采取更安全的做法至关重要。
为了帮助您(开发人员)解决此问题,我们引入了 WinForms 专用分析器。当缺少以下所有用于控制属性的 CodeDOM 序列化过程的机制时,此分析器将激活:
SerializationVisibilityAttribute:此属 投资者电子邮件列表 性控制 CodeDOM 序列化器应如何(或是否)序列化属性的内容。
该属性不是只读的,因为 CodeDOM 序列化程序默认忽略只读属性。
DefaultValueAttribute:此属性定义属性的默认值。如果应用,CodeDOM 序列化程序仅当设计时的当前值与默认值不同时才序列化该属性。
未实现相应的private bool ShouldSerialize<PropertyName>()方法。此方法在设计(序列化)时调用,以确定属性的内容是否应序列化。
通过确保至少一种机制到位,您可以避免意外的序列化行为,并确保在设计时 CodeDOM 序列化过程中正确处理您的属性。
但是...这个分析仪破坏了我的整个解决方案!
假设您已经UserControl在 .NET 8 中开发了一个特定于域的,如上面的屏幕截图所示。现在,您将项目重新定位到 .NET 9。好吧,显然,在那一刻,分析器启动了,您可能会看到类似这样的内容:
错误窗口中 WFO1000 错误的屏幕截图
与之前讨论的 Async Analyzer 不同,此分析器附加了 Roslyn CodeFix。如果您想通过指示 CodeDOM 序列化程序无条件地永不序列化属性内容来解决这个问题,您可以使用 CodeFix 进行必要的更改:
WFO1000 Roslyn CodeFix 的屏幕截图
如您所见,您甚至可以在整个文档中一次性修复它们。在大多数情况下,这已经是正确的做法:分析器SerializationVisibilityAttribute在每个标记属性的顶部添加,确保它不会被无意地序列化,这正是我们想要的:
副驾驶来救援!
还有一种更有效的方法来处理属性的必要编辑修改。您可能想问自己的问题是:如果根本没有应用任何属性来控制属性的某些方面,那么不仅要确保正确的序列化指导,还要应用其他设计时属性是否有意义?
但话又说回来,所需的努力是否会更大——或者会更大?
那么,如果我们利用 Copilot 修改设计时真正有用的所有DescriptionAttribute相关属性,如或 , 会怎么样CategoryAttribute?让我们尝试一下,像这样:
Copilot 请求修改设计时属性的屏幕截图
根据您为 Copilot 选择的语言模型,您应该看到一个结果,我们不仅解决了分析器指出的问题,而且 Copilot 还负责添加在上下文中有意义的其余属性。
Copilot 向您显示它想要添加的代码,您只需单击鼠标即可合并建议的更改。
Copilot 准备合并建议的更改的屏幕截图
而且,这些问题肯定不是 Copilot 在使您现有的 WinForms 应用程序现代化方面能够提供巨大帮助的唯一领域。
但是,如果分析器在整个解决方案中标记了数百个问题,请不要惊慌!还有更多选项可以在代码文件、项目甚至解决方案级别配置分析器的严重性:
根据范围抑制分析器
首先,您可以选择抑制不同范围内的分析器:
在源代码中:此选项直接在源文件中标记的代码周围插入 #pragma warning disable 指令。此方法适用于本地化、一次性抑制,其中分析器警告是不必要的或无关的。例如:
通过属性在源代码中:这会将抑制属性直接应用于特定代码元素,例如类或属性。当您希望抑制保留为源代码文档的一部分时,这是一个不错的选择。例如:
要为您的项目或解决方案集中配置分析器严重性,您可以使用.editorconfig文件。此文件允许您为特定分析器定义规则,包括其严重性级别,例如无、建议、警告或错误。例如,要更改 WFO1000 分析器的严重性:
复制
# Configure the severity for the WFO1000 analyzer
dotnet_diagnostic.WFO1000.severity = warning
使用 .editorconfig 文件进行目录特定设置
.editorconfig 文件的强大功能之一是它们能够控制解决方案不同部分的设置。通过将.editorconfig文件放置在解决方案内的不同目录中,您可以将设置仅应用于特定项目、文件夹或文件。配置按层次结构应用,这意味着子目录的 .editorconfig 文件中的设置可以覆盖父目录中的设置。
例如:
根级 .editorconfig:将通用 .editorconfig 文件放置在解决方案根目录中,以定义适用于整个解决方案的默认设置。
项目特定的 .editorconfig:将另一个 .editorconfig 文件放在特定项目的目录中,以便在从根目录继承设置的同时为该项目应用不同的规则。
文件夹特定的 .editorconfig:如果某些文件夹(例如,测试项目、遗留代码)需要唯一设置,则可以向这些文件夹添加 .editorconfig 文件来覆盖继承的配置。
在此布局中,根目录中的.editorconfig将常规设置应用于解决方案中的所有文件。ProjectA中的.editorconfig将应用特定于 ProjectA 的附加或覆盖规则。同样,ProjectB和Shared 目录可以定义其独特设置。
目录特定的 .editorconfig 文件测试项目的用例: 禁用或降低某些测试项目的某些分析器的严重性,其中一些规则可能不适用。
复制
# In TestProject/.editorconfig
dotnet_diagnostic.WFO1000.severity = none
Legacy Code: Suppress analyzers entirely or reduce their impact for legacy codebases to avoid unnecessary noise.
复制
# In LegacyCode/.editorconfig
dotnet_diagnostic.WFO1000.severity = suggestion
Experimental Features: Use more lenient settings for projects under active development while enforcing stricter rules for production-ready code.
通过策略性地放置 .editorconfig 文件,您可以对分析器的行为和编码约定进行精细控制,从而更轻松地管理具有各种需求的大型解决方案。请记住,此分析器的目标是指导您编写更安全、更易于维护的代码,但由您决定在项目中解决这些问题的最佳速度和优先级。
如您所见:.editorconfig文件或经过深思熟虑的一组此类文件提供了一种集中且一致的方式来管理整个项目或团队的分析器行为。
有关更多详细信息,请参阅.editorconfig 文档。
那么,我对 WinForms 分析器有一些好的想法 — — 我可以贡献吗?
当然!WinForms 团队和社区一直在寻找改善开发人员体验的想法。如果您对新分析器或现有分析器的增强功能有建议,请按以下方式做出贡献:
打开问题:前往WinForms GitHub 存储库并打开一个问题来描述您的想法。尽可能详细地解释您的分析器将解决的问题以及它如何工作。
加入讨论:在 GitHub 或其他论坛上与 WinForms 社区互动。其他开发人员的反馈可以帮助您完善想法。
贡献代码:如果您熟悉 .NET Roslyn 分析器框架,请考虑实现您的想法并向存储库提交拉取请求。团队会积极审查和合并社区贡献。
测试和迭代:在提交拉取请求之前,请使用真实场景彻底测试您的分析器,以确保它按预期工作并且不会引入误报。
为生态系统做出贡献不仅可以帮助他人,还可以加深您对 WinForms 开发和 .NET 平台的理解。
最后的话
分析器是帮助开发人员编写更好、更可靠、更安全的代码的强大工具。虽然它们最初看起来可能很烦人(尤其是当它们标记出许多问题时),但它们可以充当安全网,指导您避免常见的陷阱并采用最佳做法。
新的 WinForms 专用分析器是我们持续努力的一部分,旨在使平台现代化和保护,同时保持其简单易用性。无论您是在处理旧版应用程序还是构建新应用程序,这些工具都旨在让您的开发体验更加顺畅。
如果您遇到问题或有改进想法,我们很乐意听取您的意见!WinForms 因其热情而专注的社区而蓬勃发展了数十年,您的贡献确保了它在当今的发展格局中不断发展并保持相关性。
设计器中典型业务线用户控件的屏幕截图
如果未正确配置这些属性以控制其代码序列化行为,则设计时设置的敏感数据可能会无意中泄漏到生成的代码中。此类泄漏可能导致:
源代码中暴露的敏感数据可能会发布在 GitHub 等平台上。
设计时数据被嵌入到资源文件中,可能是因为缺少相关属性类型所需的 TypeConverters,或者是因为表单已本地化。
这两种情况都会对应用程序的完整性和安全性造成重大风险。
此外,我们力求尽可能避免资源序列化。在 .NET 9 中, 由于安全性和可维护性问题,二进制格式化程序和相关 API 已被淘汰。这使得仔细控制序列化哪些数据以及如何序列化变得更加重要。
二进制格式化程序过去用于序列化对象,但它存在许多安全漏洞,因此不适合现代应用程序。在 .NET 9 中,我们完全消除了这个序列化程序,以减少攻击面并提高应用程序的可靠性。任何对资源序列化的依赖都有可能再次引入这些风险,因此采取更安全的做法至关重要。
为了帮助您(开发人员)解决此问题,我们引入了 WinForms 专用分析器。当缺少以下所有用于控制属性的 CodeDOM 序列化过程的机制时,此分析器将激活:
SerializationVisibilityAttribute:此属 投资者电子邮件列表 性控制 CodeDOM 序列化器应如何(或是否)序列化属性的内容。
该属性不是只读的,因为 CodeDOM 序列化程序默认忽略只读属性。
DefaultValueAttribute:此属性定义属性的默认值。如果应用,CodeDOM 序列化程序仅当设计时的当前值与默认值不同时才序列化该属性。
未实现相应的private bool ShouldSerialize<PropertyName>()方法。此方法在设计(序列化)时调用,以确定属性的内容是否应序列化。
通过确保至少一种机制到位,您可以避免意外的序列化行为,并确保在设计时 CodeDOM 序列化过程中正确处理您的属性。
但是...这个分析仪破坏了我的整个解决方案!
假设您已经UserControl在 .NET 8 中开发了一个特定于域的,如上面的屏幕截图所示。现在,您将项目重新定位到 .NET 9。好吧,显然,在那一刻,分析器启动了,您可能会看到类似这样的内容:
错误窗口中 WFO1000 错误的屏幕截图
与之前讨论的 Async Analyzer 不同,此分析器附加了 Roslyn CodeFix。如果您想通过指示 CodeDOM 序列化程序无条件地永不序列化属性内容来解决这个问题,您可以使用 CodeFix 进行必要的更改:
WFO1000 Roslyn CodeFix 的屏幕截图
如您所见,您甚至可以在整个文档中一次性修复它们。在大多数情况下,这已经是正确的做法:分析器SerializationVisibilityAttribute在每个标记属性的顶部添加,确保它不会被无意地序列化,这正是我们想要的:
副驾驶来救援!
还有一种更有效的方法来处理属性的必要编辑修改。您可能想问自己的问题是:如果根本没有应用任何属性来控制属性的某些方面,那么不仅要确保正确的序列化指导,还要应用其他设计时属性是否有意义?
但话又说回来,所需的努力是否会更大——或者会更大?
那么,如果我们利用 Copilot 修改设计时真正有用的所有DescriptionAttribute相关属性,如或 , 会怎么样CategoryAttribute?让我们尝试一下,像这样:
Copilot 请求修改设计时属性的屏幕截图
根据您为 Copilot 选择的语言模型,您应该看到一个结果,我们不仅解决了分析器指出的问题,而且 Copilot 还负责添加在上下文中有意义的其余属性。
Copilot 向您显示它想要添加的代码,您只需单击鼠标即可合并建议的更改。
Copilot 准备合并建议的更改的屏幕截图
而且,这些问题肯定不是 Copilot 在使您现有的 WinForms 应用程序现代化方面能够提供巨大帮助的唯一领域。
但是,如果分析器在整个解决方案中标记了数百个问题,请不要惊慌!还有更多选项可以在代码文件、项目甚至解决方案级别配置分析器的严重性:
根据范围抑制分析器
首先,您可以选择抑制不同范围内的分析器:
在源代码中:此选项直接在源文件中标记的代码周围插入 #pragma warning disable 指令。此方法适用于本地化、一次性抑制,其中分析器警告是不必要的或无关的。例如:
通过属性在源代码中:这会将抑制属性直接应用于特定代码元素,例如类或属性。当您希望抑制保留为源代码文档的一部分时,这是一个不错的选择。例如:
要为您的项目或解决方案集中配置分析器严重性,您可以使用.editorconfig文件。此文件允许您为特定分析器定义规则,包括其严重性级别,例如无、建议、警告或错误。例如,要更改 WFO1000 分析器的严重性:
复制
# Configure the severity for the WFO1000 analyzer
dotnet_diagnostic.WFO1000.severity = warning
使用 .editorconfig 文件进行目录特定设置
.editorconfig 文件的强大功能之一是它们能够控制解决方案不同部分的设置。通过将.editorconfig文件放置在解决方案内的不同目录中,您可以将设置仅应用于特定项目、文件夹或文件。配置按层次结构应用,这意味着子目录的 .editorconfig 文件中的设置可以覆盖父目录中的设置。
例如:
根级 .editorconfig:将通用 .editorconfig 文件放置在解决方案根目录中,以定义适用于整个解决方案的默认设置。
项目特定的 .editorconfig:将另一个 .editorconfig 文件放在特定项目的目录中,以便在从根目录继承设置的同时为该项目应用不同的规则。
文件夹特定的 .editorconfig:如果某些文件夹(例如,测试项目、遗留代码)需要唯一设置,则可以向这些文件夹添加 .editorconfig 文件来覆盖继承的配置。
在此布局中,根目录中的.editorconfig将常规设置应用于解决方案中的所有文件。ProjectA中的.editorconfig将应用特定于 ProjectA 的附加或覆盖规则。同样,ProjectB和Shared 目录可以定义其独特设置。
目录特定的 .editorconfig 文件测试项目的用例: 禁用或降低某些测试项目的某些分析器的严重性,其中一些规则可能不适用。
复制
# In TestProject/.editorconfig
dotnet_diagnostic.WFO1000.severity = none
Legacy Code: Suppress analyzers entirely or reduce their impact for legacy codebases to avoid unnecessary noise.
复制
# In LegacyCode/.editorconfig
dotnet_diagnostic.WFO1000.severity = suggestion
Experimental Features: Use more lenient settings for projects under active development while enforcing stricter rules for production-ready code.
通过策略性地放置 .editorconfig 文件,您可以对分析器的行为和编码约定进行精细控制,从而更轻松地管理具有各种需求的大型解决方案。请记住,此分析器的目标是指导您编写更安全、更易于维护的代码,但由您决定在项目中解决这些问题的最佳速度和优先级。
如您所见:.editorconfig文件或经过深思熟虑的一组此类文件提供了一种集中且一致的方式来管理整个项目或团队的分析器行为。
有关更多详细信息,请参阅.editorconfig 文档。
那么,我对 WinForms 分析器有一些好的想法 — — 我可以贡献吗?
当然!WinForms 团队和社区一直在寻找改善开发人员体验的想法。如果您对新分析器或现有分析器的增强功能有建议,请按以下方式做出贡献:
打开问题:前往WinForms GitHub 存储库并打开一个问题来描述您的想法。尽可能详细地解释您的分析器将解决的问题以及它如何工作。
加入讨论:在 GitHub 或其他论坛上与 WinForms 社区互动。其他开发人员的反馈可以帮助您完善想法。
贡献代码:如果您熟悉 .NET Roslyn 分析器框架,请考虑实现您的想法并向存储库提交拉取请求。团队会积极审查和合并社区贡献。
测试和迭代:在提交拉取请求之前,请使用真实场景彻底测试您的分析器,以确保它按预期工作并且不会引入误报。
为生态系统做出贡献不仅可以帮助他人,还可以加深您对 WinForms 开发和 .NET 平台的理解。
最后的话
分析器是帮助开发人员编写更好、更可靠、更安全的代码的强大工具。虽然它们最初看起来可能很烦人(尤其是当它们标记出许多问题时),但它们可以充当安全网,指导您避免常见的陷阱并采用最佳做法。
新的 WinForms 专用分析器是我们持续努力的一部分,旨在使平台现代化和保护,同时保持其简单易用性。无论您是在处理旧版应用程序还是构建新应用程序,这些工具都旨在让您的开发体验更加顺畅。
如果您遇到问题或有改进想法,我们很乐意听取您的意见!WinForms 因其热情而专注的社区而蓬勃发展了数十年,您的贡献确保了它在当今的发展格局中不断发展并保持相关性。