Skip to content

fix(WPF): deny WPF Behaviors namespaces in untrusted homepage XAML#3049

Open
lhx077 wants to merge 1 commit into
devfrom
codex/propose-fix-for-wpf-behaviors-vulnerability
Open

fix(WPF): deny WPF Behaviors namespaces in untrusted homepage XAML#3049
lhx077 wants to merge 1 commit into
devfrom
codex/propose-fix-for-wpf-behaviors-vulnerability

Conversation

@lhx077

@lhx077 lhx077 commented Jun 6, 2026

Copy link
Copy Markdown
Member

Motivation

  • The project added Microsoft.Xaml.Behaviors.Wpf and a TriggerAction-derived animation action (RunAnimationAction), which expands the XAML surface and enables generic behavior actions that can invoke methods from untrusted homepage XAML.
  • Prevent attacker-supplied homepage markup from referencing behavior types (e.g., CallMethodAction/ChangePropertyAction) that could enable arbitrary method/property invocation.

Description

  • Add a pre-parse namespace denylist in ModBase.GetObjectFromXML(string) that scans the XAML string and throws UnauthorizedAccessException when it contains any of Microsoft.Xaml.Behaviors, Microsoft.Xaml.Behaviors.Core, Microsoft.Xaml.Interactions.Core, or http://schemas.microsoft.com/xaml/behaviors.
  • Preserve the existing compatibility rewrites and the XamlXmlReader-based type/member blacklist and continue to load via XamlReader.Load when checks pass.

Testing

  • Verified the denylist insertion with a local Python presence check that confirms the new namespace checks are present and would trigger the UnauthorizedAccessException path.
  • Ran repository checks including git diff --check to ensure no style/whitespace issues were introduced.
  • Could not run dotnet build 'Plain Craft Launcher 2/Plain Craft Launcher 2.csproj' -c Debug -v:minimal in this environment because dotnet is not installed, so compilation was not validated here.

Codex Task

Summary by Sourcery

错误修复:

  • 当不受信任的主页 XAML 引用 Microsoft.Xaml.Behaviors 或相关行为命名空间时,在解析之前抛出 UnauthorizedAccessException,以防止加载这些 XAML。
Original summary in English

Summary by Sourcery

Bug Fixes:

  • Prevent untrusted homepage XAML from loading when it references Microsoft.Xaml.Behaviors or related behaviors namespaces by throwing an UnauthorizedAccessException before parsing.

@pcl-ce-automation pcl-ce-automation Bot added 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 size: S PR 大小评估:小型 and removed codex labels Jun 6, 2026
@sourcery-ai

sourcery-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown
审阅者指南(在小型 PR 上折叠)

审阅者指南

ModBase.GetObjectFromXML 中添加预解析 XAML 命名空间拒绝列表(denylist),用于在不可信的主页 XAML 中阻止不安全的 WPF Behaviors 命名空间,同时保留现有的兼容性重写和基于 XamlXmlReader 的检查。

更新后的 ModBase.GetObjectFromXML XAML 安全检查顺序图

sequenceDiagram
    participant HomepageLoader
    participant ModBase
    participant XamlReader

    HomepageLoader->>ModBase: GetObjectFromXML(str)
    ModBase->>ModBase: Apply compatibility Replace calls
    ModBase->>ModBase: Scan for blockedXamlNamespace
    alt blocked namespace found
        ModBase-->>HomepageLoader: throw UnauthorizedAccessException
    else no blocked namespace
        ModBase->>XamlReader: Load(stream)
        XamlReader-->>ModBase: object
        ModBase-->>HomepageLoader: object
    end
Loading

文件级更改

变更 详情 文件
添加预解析拒绝列表,在不可信的主页 XAML 中阻止不安全的 WPF Behaviors 命名空间,一旦遇到则抛出 UnauthorizedAccessException
  • 在 XAML 解析之前插入一个 foreach 循环,遍历一个硬编码的被阻止 WPF Behaviors 命名空间和架构(schema)URL 列表。
  • 对原始 XAML 文本针对每个被阻止命名空间执行不区分大小写的字符串检查。
  • 当发现被阻止命名空间时,抛出带有本地化错误消息的 UnauthorizedAccessException,中止后续处理和解析。
Plain Craft Launcher 2/Modules/Base/ModBase.cs

提示与命令

与 Sourcery 交互

  • 触发新的代码审阅: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 在某条审阅评论下回复,要求 Sourcery 基于该评论创建 issue。你也可以直接回复 @sourcery-ai issue 来从该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文的任意位置写上 @sourcery-ai summary,即可在你想要的位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来在任何时候(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可在任何时候(重新)生成审阅者指南。
  • 批量解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve 来将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 审阅: 在 pull request 中评论 @sourcery-ai dismiss 来忽略所有现有的 Sourcery 审阅。尤其适用于你想从头开始一次新的审阅——别忘了评论 @sourcery-ai review 来触发新的审阅!

自定义你的体验

访问你的 控制面板 来:

  • 启用或禁用审阅功能,如 Sourcery 生成的 pull request 摘要、审阅者指南等。
  • 更改审阅使用的语言。
  • 添加、删除或编辑自定义审阅指令。
  • 调整其他审阅设置。

获取帮助

Original review guide in English
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a pre-parse XAML namespace denylist in ModBase.GetObjectFromXML to block unsafe WPF Behaviors namespaces in untrusted homepage XAML while preserving existing compatibility rewrites and XamlXmlReader-based checks.

Sequence diagram for updated ModBase.GetObjectFromXML XAML security checks

sequenceDiagram
    participant HomepageLoader
    participant ModBase
    participant XamlReader

    HomepageLoader->>ModBase: GetObjectFromXML(str)
    ModBase->>ModBase: Apply compatibility Replace calls
    ModBase->>ModBase: Scan for blockedXamlNamespace
    alt blocked namespace found
        ModBase-->>HomepageLoader: throw UnauthorizedAccessException
    else no blocked namespace
        ModBase->>XamlReader: Load(stream)
        XamlReader-->>ModBase: object
        ModBase-->>HomepageLoader: object
    end
Loading

File-Level Changes

Change Details Files
Add a pre-parse denylist that blocks unsafe WPF Behaviors namespaces in untrusted homepage XAML and throws UnauthorizedAccessException when encountered.
  • Insert a foreach loop before XAML parsing that iterates over a hard-coded list of blocked WPF Behaviors namespaces and schema URLs.
  • Perform case-insensitive string checks against the raw XAML for each blocked namespace.
  • Throw UnauthorizedAccessException with a localized error message when a blocked namespace is found, aborting further processing and parsing.
Plain Craft Launcher 2/Modules/Base/ModBase.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - 我在这里给出一些高层面的反馈:

  • string.Contains(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) 这个重载在较旧的 .NET Framework 目标中不可用;为避免潜在的编译问题,建议改用 IndexOf(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) >= 0
  • 被阻止的 XAML 命名空间列表在每次调用 GetObjectFromXML 时都会被重新分配;这是一个热点路径,建议将该列表移动到一个静态 readonly 字段中,以避免重复的数组分配。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- The `string.Contains(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase)` overload is not available on older .NET Framework targets; consider using `IndexOf(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) >= 0` instead to avoid potential compilation issues.
- The blocked XAML namespace list is reallocated on every `GetObjectFromXML` call; consider moving it to a static readonly field to avoid repeated array allocations in this hot path.

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈来改进后续的评审。
Original comment in English

Hey - I've left some high level feedback:

  • The string.Contains(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) overload is not available on older .NET Framework targets; consider using IndexOf(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) >= 0 instead to avoid potential compilation issues.
  • The blocked XAML namespace list is reallocated on every GetObjectFromXML call; consider moving it to a static readonly field to avoid repeated array allocations in this hot path.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `string.Contains(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase)` overload is not available on older .NET Framework targets; consider using `IndexOf(blockedXamlNamespace, StringComparison.OrdinalIgnoreCase) >= 0` instead to avoid potential compilation issues.
- The blocked XAML namespace list is reallocated on every `GetObjectFromXML` call; consider moving it to a static readonly field to avoid repeated array allocations in this hot path.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@lhx077 lhx077 changed the title fix: deny WPF Behaviors namespaces in untrusted homepage XAML fix(WPF): deny WPF Behaviors namespaces in untrusted homepage XAML Jun 6, 2026
Replace("Property=\"EventData\"", "Property=\"local:CustomEventService.EventData\"");

// 自定义主页 XAML 被视为不受信任内容;禁止引用 WPF Behaviors 中可调用方法/改写属性的通用动作。
foreach (var blockedXamlNamespace in new[]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i think u can make a static readonly array

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: S PR 大小评估:小型 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants