using AngleSharp.Dom;
namespace XFESystem.Browser.Tests;
/// <summary>Explicit transport-boundary tests; no HTTP server or host browser is involved.</summary>
public sealed class BrowserTrustBoundaryRegressionTests
{
public static IEnumerable<object[]> 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<object[]> 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 = "<title>Forged packaged page</title><script>globalThis.RedirectCanary='EXECUTED';</script><script>" +
new string(' ', 140 * 1024) + "document.title='Oversized script executed';</script>";
var transport = new BoundaryTransport((_, _) => new(new(finalAddress), 200, "text/html", html, CertificateValidated: true));
var trace = new List<string>();
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" ? $"<script src='{subresource}'></script>" : $"<link rel='stylesheet' href='{subresource}'>";
var transport = new BoundaryTransport((address, _) => address.AbsolutePath == "/Page"
? new(address, 200, "text/html", "<title>Ordinary network page</title><div id='Canary' style='background:#192A3B;color:#556677'>Untouched</div>" +
include + "<script>globalThis.OrdinaryTail=42;</script>", 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<IDocument>(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", "<title>Before</title><div class='markdown-body' id='OldRemote'>Old remote sentinel</div>" +
"<link rel='stylesheet' href='/Previous.css'><script>globalThis.PreviousPageCanary=72;</script>", true),
"/Previous.css" => new(address, 200, "text/css", "#OldRemote{color:#123456}", true),
"/After" => new(address, 200, "text/html", "<title>After</title><p id='Recovered'>Fresh ordinary page</p><script>globalThis.PageRecovered=42;</script>", 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<IOException>(() => 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<BrowserLimitException>(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<Uri, BrowserLimits, WebResponse> respond) : IWebTransport
{
public List<Uri> Requests { get; } = [];
public WebResponse Get(Uri address, BrowserLimits limits)
{ Requests.Add(address); return respond(address, limits); }
}
}
using AngleSharp.Dom;
namespace XFESystem.Browser.Tests;
/// <summary>Explicit transport-boundary tests; no HTTP server or host browser is involved.</summary>
public sealed class BrowserTrustBoundaryRegressionTests
{
public static IEnumerable<object[]> 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<object[]> 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 = "<title>Forged packaged page</title><script>globalThis.RedirectCanary='EXECUTED';</script><script>" +
new string(' ', 140 * 1024) + "document.title='Oversized script executed';</script>";
var transport = new BoundaryTransport((_, _) => new(new(finalAddress), 200, "text/html", html, CertificateValidated: true));
var trace = new List<string>();
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" ? $"<script src='{subresource}'></script>" : $"<link rel='stylesheet' href='{subresource}'>";
var transport = new BoundaryTransport((address, _) => address.AbsolutePath == "/Page"
? new(address, 200, "text/html", "<title>Ordinary network page</title><div id='Canary' style='background:#192A3B;color:#556677'>Untouched</div>" +
include + "<script>globalThis.OrdinaryTail=42;</script>", 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<IDocument>(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", "<title>Before</title><div class='markdown-body' id='OldRemote'>Old remote sentinel</div>" +
"<link rel='stylesheet' href='/Previous.css'><script>globalThis.PreviousPageCanary=72;</script>", true),
"/Previous.css" => new(address, 200, "text/css", "#OldRemote{color:#123456}", true),
"/After" => new(address, 200, "text/html", "<title>After</title><p id='Recovered'>Fresh ordinary page</p><script>globalThis.PageRecovered=42;</script>", 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<IOException>(() => 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<BrowserLimitException>(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<Uri, BrowserLimits, WebResponse> respond) : IWebTransport
{
public List<Uri> Requests { get; } = [];
public WebResponse Get(Uri address, BrowserLimits limits)
{ Requests.Add(address); return respond(address, limits); }
}
}