using AngleSharp.Dom; namespace XFESystem.Browser.Tests; /// Explicit transport-boundary tests; no HTTP server or host browser is involved. public sealed class BrowserTrustBoundaryRegressionTests { public static IEnumerable ReservedFinalAddresses() { foreach (var address in new[] { "http://xfesystem.local/Browser/Monaco/Index.html", "http://XFESYSTEM.LOCAL:80/Browser/Monaco/Index.html?language=csharp", "http://XfeSystem.Local:8080/Browser/Monaco/Index.html", "https://xfesystem.local/Browser/Monaco/Index.html", "https://XFESYSTEM.LOCAL:443/Browser/Monaco/Index.html?language=csharp", "https://XfeSystem.Local:444/Browser/Monaco/Index.html", "http://xfesystem.local:65535/Documents/Preview/Index.html" }) yield return [address]; } public static IEnumerable ReservedSubresourceAddresses() { foreach (var row in ReservedFinalAddresses()) { yield return [row[0], "script"]; yield return [row[0], "style"]; } } [Theory] [MemberData(nameof(ReservedFinalAddresses))] public void NetworkFinalAddressCannotImpersonateAnyReservedHostOrAcquireThePackagedScriptBudget(string finalAddress) { const string requested = "http://network.test/Redirect"; var html = "Forged packaged page"; var transport = new BoundaryTransport((_, _) => new(new(finalAddress), 200, "text/html", html, CertificateValidated: true)); var trace = new List(); var browser = new BrowserService(transport) { Trace = trace.Add }; var page = browser.Navigate(requested); Assert.Equal("Navigation failed", page.Title); Assert.Contains("A network response cannot impersonate a packaged XFESystem page.", page.Text, StringComparison.Ordinal); Assert.DoesNotContain("Oversized script executed", page.Text, StringComparison.Ordinal); Assert.Empty(trace); // No document script/style dispatch began. AssertCleared(browser); Assert.Equal(requested, Assert.Single(transport.Requests).AbsoluteUri); Assert.Equal("undefined", browser.ExecuteJavaScript("typeof RedirectCanary")); } [Theory] [MemberData(nameof(ReservedSubresourceAddresses))] public void NetworkSubresourceRedirectsToReservedHostsAreRejectedBeforeExecutionOrStyleAdoption(string finalAddress, string kind) { const string requested = "http://network.test/Page"; var subresource = kind == "script" ? "Foreign.js" : "Foreign.css"; var include = kind == "script" ? $"" : $""; var transport = new BoundaryTransport((address, _) => address.AbsolutePath == "/Page" ? new(address, 200, "text/html", "Ordinary network page
Untouched
" + include + "", true) : new(new(finalAddress), 200, kind == "script" ? "application/javascript" : "text/css", kind == "script" ? "globalThis.SubresourceCanary='EXECUTED';document.getElementById('Canary').textContent='PWNED';" : "#Canary{background:#FF3355;color:#112233;width:313px}", true)); var browser = new BrowserService(transport); var page = browser.Navigate(requested); Assert.Equal("Ordinary network page", page.Title); Assert.Contains(kind == "script" ? "External script failed:" : "Stylesheet failed:", page.Text, StringComparison.Ordinal); Assert.Contains("A network subresource cannot impersonate a bundled resource.", page.Text, StringComparison.Ordinal); var document = Assert.IsAssignableFrom(browser.Document); Assert.Equal("Untouched", document.GetElementById("Canary")!.TextContent); Assert.Equal("undefined", browser.ExecuteJavaScript("typeof SubresourceCanary")); Assert.Equal("42", browser.ExecuteJavaScript("OrdinaryTail")); var style = browser.Layout(new(600, 400)).GetComputedStyle(document.GetElementById("Canary")!); Assert.NotNull(style); Assert.Equal(0x192A3Bu, style.Background.Rgb); Assert.Equal(0x556677u, style.Color.Rgb); Assert.Empty(browser.LoadedResources); Assert.Equal("{}", browser.ReadWebsiteDocumentProof()); Assert.Equal("{}", browser.ReadMonacoProof()); Assert.Equal(new[] { requested, "http://network.test/" + subresource }, transport.Requests.Select(uri => uri.AbsoluteUri)); } [Fact] public void ExpandedLocalDocumentFailureClearsPreviousRemoteDomResourcesAndTrustThenAllowsNormalNavigation() { var transport = new BoundaryTransport((address, _) => address.AbsolutePath switch { "/Before" => new(address, 200, "text/html", "Before
Old remote sentinel
" + "", true), "/Previous.css" => new(address, 200, "text/css", "#OldRemote{color:#123456}", true), "/After" => new(address, 200, "text/html", "After

Fresh ordinary page

", true), _ => throw new InvalidOperationException("Unexpected boundary fixture address: " + address) }); var browser = new BrowserService(transport); browser.Navigate("http://network.test/Before"); Assert.NotNull(browser.Document!.QuerySelector(".markdown-body#OldRemote")); Assert.Single(browser.LoadedResources); Assert.Equal("72", browser.ExecuteJavaScript("PreviousPageCanary")); // Source fits the one-MiB source limit, while HTML entity expansion alone // produces over one MiB. The failure therefore occurs inside LoadHtml. var error = Assert.Throws(() => browser.NavigateDocument(new string('&', 256 * 1024), "Expanded.md")); Assert.Contains("Document preview failed:", error.Message, StringComparison.Ordinal); Assert.Contains("The document exceeds its character limit.", error.Message, StringComparison.Ordinal); Assert.IsType(error.InnerException); Assert.Equal("Navigation failed", browser.CurrentPage.Title); Assert.DoesNotContain("Old remote sentinel", browser.CurrentPage.Text, StringComparison.Ordinal); AssertCleared(browser); var after = browser.Navigate("http://network.test/After"); Assert.Equal("After", after.Title); Assert.Equal("Fresh ordinary page", browser.Document!.GetElementById("Recovered")!.TextContent); Assert.Null(browser.Document.GetElementById("OldRemote")); Assert.Equal("undefined", browser.ExecuteJavaScript("typeof PreviousPageCanary")); Assert.Equal("42", browser.ExecuteJavaScript("PageRecovered")); var oversized = browser.ExecuteJavaScript(new string(' ', 140 * 1024) + "globalThis.AccidentalTrustedBudget=true;"); Assert.Contains("The script exceeds its character limit.", oversized, StringComparison.Ordinal); Assert.Equal("undefined", browser.ExecuteJavaScript("typeof AccidentalTrustedBudget")); Assert.Empty(browser.LoadedResources); Assert.Equal("{}", browser.ReadWebsiteDocumentProof()); Assert.Equal("{}", browser.ReadMonacoProof()); } private static void AssertCleared(BrowserService browser) { Assert.Null(browser.Document); Assert.Empty(browser.LoadedResources); Assert.Equal("{}", browser.ReadWebsiteDocumentProof()); Assert.Equal("{}", browser.ReadMonacoProof()); Assert.Null(browser.Document); // Read-only proof calls cannot recreate a stale DOM. } private sealed class BoundaryTransport(Func respond) : IWebTransport { public List Requests { get; } = []; public WebResponse Get(Uri address, BrowserLimits limits) { Requests.Add(address); return respond(address, limits); } } }