Skip to content

Protect email and agent HTML sanitizer compatibility - #13995

Queued
Niels-Henrik Sejthen (nhsejth) wants to merge 3 commits into
mainfrom
private/nhsejth/642579-html-sanitizer
Queued

Niels-Henrik Sejthen (nhsejth) wants to merge 3 commits into
mainfrom
private/nhsejth/642579-html-sanitizer

Conversation

@nhsejth

@nhsejth Niels-Henrik Sejthen (nhsejth) commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

What & why

Add eight regression tests protecting the Email Message and Agent Message callers of the platform HTML sanitizer during its coordinated dependency upgrade.

The tests preserve basic formatting and encoded text, reject unsupported styling/event handlers and both MathML HTML integration encodings, and protect the existing plain-text and explicitly disabled-sanitization paths.

Investigation, compilation, and runtime testing demonstrate that the existing DotNet alias and SanitizeEmail contract remain compatible. No production AL change is required or included.

Linked work

Fixes #13994

AB#642579

The linked issue is approved. The component-governance remediation is a separate platform dependency/add-in change.

How I validated this

  • I read the full diff and it contains only changes I intended.
  • I built the affected app(s) locally with no new analyzer warnings.
  • I ran the change in Business Central and confirmed it behaves as expected.
  • I added or updated tests for the new behavior, or explained below why none are needed.

What I tested and the outcome

Compiled Email Test, Agent Test, and the required module dependency closure using Compile-ALProject, the repository's src\rulesets\internal.module.ruleset.json, and the patched platform add-in/dependency assemblies. There were no diagnostics in either changed file. Four AA0139 warnings are limited to unchanged Email test/library sources.

Executed exactly these eight new methods with the modern AL Test Runner in a dedicated database/NST:

Codeunit Methods Result
134689 Email Message Unit Test CreateMessageWithSanitizationPreservesBasicFormatting, CreateMessageWithSanitizationRemovesMathmlIntegrationPoints, CreateMessageWithSanitizationRemovesXhtmlMathmlIntegrationPoints, CreatePlainTextMessageDoesNotApplyHtmlSanitization, CreateHtmlMessageCanKeepSanitizationDisabled 5 passed
133963 Agent Message Test SanitizeMessagePreservesBasicFormatting, SanitizeMessageRemovesMathmlIntegrationPoints, SanitizeMessageRemovesXhtmlMathmlIntegrationPoints 3 passed

Each encoding has an independent test procedure with one [WHEN] action. Both codeunits reported success; genuine Test Runner JSON results and derived TRX diagnostics were retained. Full Email/Agent suites were not executed.

The task-owned NST used verified AngleSharp 1.6.0, AngleSharp.Css 1.0.0, and HtmlSanitizer 9.1.973 assemblies. It was stopped afterwards. Existing shared NST service states and executable/config paths were unchanged.

Risk & compatibility

Regression tests only: no production application behavior/API, permissions, schema, data upgrade, telemetry, or feature-flag changes. No assertion that the old restrictive email allowlist was exploitable. Release-branch platform backports and component-governance rescans remain separate follow-up work.

…ependency upgrade

Fixes #13994
AB#642579

Add four Email Message regressions through the existing public Create
overload and two Agent Message regressions through the existing internal
wrapper. Verify basic formatting and encoded text survive while styles,
event handlers, and MathML annotation-xml foreign content are removed.
Exercise both text/html and application/xhtml+xml integration encodings.
Protect the existing plain-text path and explicit HTML sanitization opt-out.

The application references the stable AppHtmlSanitizer DotNet alias rather
than AngleSharp APIs. Compilation and runtime evidence demonstrate that
the coordinated platform dependency upgrade requires no production AL
change, new API, data migration, permissions change, or feature flag.
Keep this application change regression-only.

Validation:
- Compiled Email Test, Agent Test and their dependency closure with the
  repository's internal-module CodeCop ruleset and patched platform add-in.
- No analyzer diagnostics in the two changed files; four AA0139 warnings
  are confined to unchanged Email test/library sources.
- Executed exactly the six new methods using the modern AL Test Runner
  in a separately provisioned database/NST with the patched dependencies.
  All six methods and both test codeunits reported success.
- Preserved the genuine JSON results and generated TRX diagnostics from
  those results. Full Email/Agent suites were not executed.
- The dedicated NST was stopped afterwards. Existing shared NST service
  states and executable/config paths were unchanged.

The component-governance fix is in the separate platform change.
These tests do not claim the old restrictive email allowlist was exploitable.
Affected release branches still need platform backports and CG rescans.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4880f3b9-e4b5-4124-bfaf-74629b812e2f
AB#642579

Address both review threads in PR 13995 by adding SCENARIO, GIVEN, WHEN and THEN tags to all six new tests. Make agent sanitization an explicit action before its assertions and retain the original integration-point payload for both HTML encodings. Preserve test names, expectations, plain-text behavior and the explicit sanitization opt-out.

Rebuilt Email Test and Agent Test with the existing internal-module CodeCop rules; no diagnostics in changed files. All six selected methods and both codeunits passed again in the task-owned patched NST, with genuine JSON and derived TRX results. The isolated service was returned to its stopped state. No production application or shared-environment changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4880f3b9-e4b5-4124-bfaf-74629b812e2f
Address the two follow-up testing comments on #13995.
Each MathML encoding case now has an independent procedure, local payload,
SCENARIO/GIVEN/WHEN/THEN structure, and one sanitizer action. A failure in
the HTML case no longer prevents execution or identification of the XHTML
case.

Keep the original HTML test names and add explicit XHTML tests in Email
Message Unit Test and Agent Message Test. Preserve the original sanitizer
expectations, Email permission setup and AutoRollback transaction model,
and Agent action/result separation. No production AL code, public API,
manifest, dependency, permission or schema changes.

Validation:
- Recompiled Email Test and Agent Test from an isolated PR worktree with
  the repository's internal.module.ruleset.json CodeCop rules.
- Executed all eight sanitizer regressions against the task-owned NST
  containing the patched platform dependencies: five Email and three
  Agent methods passed, and both test codeunits reported success.
- Retained genuine AL Test Runner JSON and derived TRX diagnostics.
- Verified exactly one WHEN in each of the eight sanitizer procedures
  and a clean git diff --check.
- Restored the task-owned NST's stopped state and verified existing NST
  states and executable/config paths were unchanged. Left the unrelated
  active BcApps branch and its untracked files untouched.

AB#642579

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4880f3b9-e4b5-4124-bfaf-74629b812e2f
@nhsejth
Niels-Henrik Sejthen (nhsejth) added this pull request to the merge queue Nov 13, 2026
Any commits made after this event will not be merged.

This branch was previously deployed

1 inactive (outdated) deployment
triage — 2ecdb6f5 Deployed Nov 12, 2026 by nhsejth via Classify team ownership #10843
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: System Application Team: Integrations GitHub request for Integrations area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add email and agent HTML sanitization compatibility regressions

4 participants