Skip to content

DYN-10642 Enforce no-network startup behavior for WebView2 surfaces#17212

Open
edwin-vasquez-ucaldas wants to merge 25 commits into
masterfrom
DYN-10642_Enforce_no-network_startup_for_WebView2
Open

DYN-10642 Enforce no-network startup behavior for WebView2 surfaces#17212
edwin-vasquez-ucaldas wants to merge 25 commits into
masterfrom
DYN-10642_Enforce_no-network_startup_for_WebView2

Conversation

@edwin-vasquez-ucaldas

@edwin-vasquez-ucaldas edwin-vasquez-ucaldas commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Purpose

  • Configure WebView2 initialization with explicit no-network-oriented environment options/flags.
  • Ensure NoNetworkMode is threaded early enough to affect all startup WebView2 surfaces, including SplashScreen.
  • Centralize startup WebView2 policy to avoid per-view drift and regressions.
  • Add verification coverage and diagnostics required to validate no-network behavior during startup.

Declarations

Check these if you believe they are true

Release Notes

Added one place for Centralized policy that defines and applies the policy, so surfaces can't drift:

  • public const string NoNetworkAdditionalBrowserArguments — the Edge command-line switches.
  • GetNoNetworkBrowserArguments(bool) — returns the switches or null.
  • ApplyNoNetworkPolicy(CoreWebView2CreationProperties props, bool noNetworkMode, Action<string> logFn = null) — sets props.AdditionalBrowserArguments only when the flag is on, and emits a diagnostic log line (the telemetry-safe diagnostics the ticket asked for). No-op when the flag is off.
  • Added a new constructor overload SplashScreen(bool enableSignInButton, bool noNetworkMode) (the existing SplashScreen(bool enableSignInButton = true) now delegates to it, so the public API is preserved).
  • Stored noNetworkMode and applied the policy in OnContentRendered right after building CreationProperties, before Initialize().
  • DynamoViewModel.cs — NetworkUtilities.InitInternetCheck() (which allocates an HttpClient) was called unconditionally. Now guarded behind if (!Model.NoNetworkMode). CheckOnlineAccess() already short-circuits, so behavior is unchanged when the flag is off.

Reviewers

@jasonstratton @RobertGlobant20

FYIs

@jnealb

Copilot AI review requested due to automatic review settings July 7, 2026 15:36
@github-actions github-actions Bot changed the title Dyn 10642 enforce no network startup for web view2 DYN-: Dyn 10642 enforce no network startup for web view2 Jul 7, 2026

@github-actions github-actions 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.

See the ticket for this pull request: https://jira.autodesk.com/browse/DYN-10642

@edwin-vasquez-ucaldas edwin-vasquez-ucaldas changed the title DYN-: Dyn 10642 enforce no network startup for web view2 DYN-10642 Enforce no-network startup behavior for WebView2 surfaces Jul 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens Dynamo’s --NoNetworkMode startup contract by centralizing and applying a WebView2/Edge “no background networking” policy across startup WebView2 surfaces (including SplashScreen), and by gating additional network-adjacent features (connectivity probe allocation, crash report upload, ML pipeline auth wiring) when no-network mode is enabled.

Changes:

  • Adds a centralized WebView2 no-network policy (WebView2Utilities) and applies it across SplashScreen, HomePage, Library, Documentation Browser, and Package Manager wizard WebView2 instances.
  • Threads NoNetworkMode into SplashScreen construction early enough to affect the first WebView2 surface shown at startup; guards connectivity probing allocation and crash-report upload in no-network mode.
  • Adds unit tests for the centralized WebView2 policy and an explicit system-level network-egress audit test.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/System/IntegrationTests/DynamoApplicationTests.cs Adds an explicit network-egress audit test that inspects TCP connections for the DynamoSandbox process tree.
test/DynamoCoreWpfTests/WebView2NoNetworkPolicyTests.cs New unit tests validating the centralized WebView2 no-network policy behavior and diagnostics.
src/LibraryViewExtensionWebView2/LibraryViewController.cs Applies centralized WebView2 no-network policy when the model is in no-network mode.
src/DynamoSandbox/DynamoCoreSetup.cs Passes no-network mode into SplashScreen so the first WebView2 surface is hardened early.
src/DynamoMLDataPipeline/DynamoMLDataPipelineExtension.cs Skips wiring ML pipeline auth providers when no-network mode is enabled.
src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs Adds a constructor overload to carry no-network state and applies the WebView2 policy before initialization.
src/DynamoCoreWpf/Views/PackageManager/Components/PackageManagerWizard/PackageManagerWizard.xaml.cs Applies no-network policy defensively to the wizard WebView2 surface.
src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs Applies no-network policy to the HomePage WebView2 surface and logs diagnostics via the model logger.
src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs Guards connectivity-check HttpClient allocation and stop-call behind !NoNetworkMode.
src/DynamoCoreWpf/Utilities/WebView2Utilities.cs Introduces the centralized no-network policy API + constant Edge switches string.
src/DynamoCoreWpf/Utilities/CrashReportTool.cs Skips CER crash report upload in no-network mode and logs a warning.
src/DynamoCoreWpf/PublicAPI.Unshipped.txt Registers new public APIs (SplashScreen ctor overload + WebView2Utilities policy APIs/constants).
src/DocumentationBrowserViewExtension/DocumentationBrowserViewExtension.cs Propagates no-network state into the documentation browser view.
src/DocumentationBrowserViewExtension/DocumentationBrowserView.xaml.cs Applies the centralized no-network policy when NoNetworkMode is set.
doc/distrib/xml/en-US/ProtoGeometry.XML Fixes a spelling error (“cetered” → “centered”).
doc/distrib/no-network-mode.md Adds documentation for the --NoNetworkMode startup contract and WebView2 hardening details.
AGENTS.md Links the new no-network mode contract doc for agent guidance.
.claude/rules/dynamo-core-rules.md References the no-network startup contract doc in shared constraints.
Files not reviewed (1)
  • doc/distrib/xml/en-US/ProtoGeometry.XML: Generated file

Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Outdated
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs
Comment thread src/DynamoCoreWpf/Utilities/CrashReportTool.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
edwin-vasquez-ucaldas and others added 8 commits July 8, 2026 09:50
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
…ject. Remove the dependency and restored the previous Win32-based parent-PID
…ne' may silently drop its earlier arguments'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • doc/distrib/xml/en-US/ProtoGeometry.XML: Generated file

Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Outdated
Comment thread src/DynamoCoreWpf/Utilities/WebView2Utilities.cs Outdated
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
…ng direct this.startPage dereferences from the flagged execution paths in UserControl_Loaded
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • doc/distrib/xml/en-US/ProtoGeometry.XML: Generated file

Comment thread src/DynamoCoreWpf/PublicAPI.Unshipped.txt Outdated
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs
edwin-vasquez-ucaldas and others added 3 commits July 8, 2026 17:34
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Fixed
…null'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@jasonstratton jasonstratton left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have made a few comments indicating that they are low probability. If you feel it is unnecessary to address, you can reply with a comment stating so, but the others require code changes.


// This test is Explicit because it launches the full DynamoSandbox process tree (including
// WebView2/Edge child processes) and inspects live OS TCP tables.
[Test, Explicit("Network-egress audit; run on a clean, isolated machine. See comment above.")]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given this is the only test that actually verifies the no-network contract at the OS/TCP level (the others just check flag propagation), what's the intended cadence for running it — manual pre-release check, or should it be wired into a scheduled/release job?

The explanation for being an explicit test makes sense, but I think it is the only explicit test in Dynamo.

Take a look at the long running tests job, which is not run on every PR check. Or maybe discuss the AGT tests with QA as they launch full sandbox for testing.

Comment thread test/System/IntegrationTests/DynamoApplicationTests.cs Dismissed
public IntPtr InheritedFromUniqueProcessId;
}

private static int GetParentProcessId(int pid)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

GetParentProcessId returns 0 ("no parent") whenever NtQueryInformationProcess fails for any reason — not only when the process genuinely has no parent.

A protected/access-restricted child (e.g. a WebView2 process running at a different integrity level) would hit this and get misread as parentless.

This would result in terminating walking the process tree and could result in a passing test if one of the missed processes does have a network connection.

var rows = new List<TcpRow>();
int size = 0;

var result = GetExtendedTcpTable(IntPtr.Zero, ref size, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think there is a race condition introduced here. If the system-wide TCP table grows in between the GetExtendedTcpTable() call here and the one below, the second call will return ERROR_INSUFFICIENT_BUFFER again — but the code only checks for result != 0 and throws, instead of reallocating and retrying with the updated size.

The result can be intermittently flaky test failures.

See this article for details:
https://textslashplain.com/2018/08/29/error_insufficient_buffer-and-concurrency/

var rows = new List<TcpRow>();
int size = 0;

var result = GetExtendedTcpTable(IntPtr.Zero, ref size, true, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Similar to the above comment, I think there is a race condition introduced here. If the system-wide TCP table grows in between the GetExtendedTcpTable() call here and the one below, the second call will return ERROR_INSUFFICIENT_BUFFER again — but the code only checks for result != 0 and throws, instead of reallocating and retrying with the updated size.

The result can be intermittently flaky test failures.

See this article for details:
https://textslashplain.com/2018/08/29/error_insufficient_buffer-and-concurrency/

public IntPtr InheritedFromUniqueProcessId;
}

private static int GetParentProcessId(int pid)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The only client of this method is GetProcessTreePids(), which already has an open Process. If the argument is changed to take a Process object or the Process.Handle instead of the process id, it would eliminate the redundant GetProcessById() below.

{
return 0;
}
return pbi.InheritedFromUniqueProcessId.ToInt32();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a low probability of resulting in a false positive test result, but certainly plausible and should be addressed.

GetParentProcessId returns pbi.InheritedFromUniqueProcessId as-is, but Windows records that field once at process creation and never invalidates it — it's not verified against the actual current parent. If the original parent process has since exited and its PID gets reused by an unrelated process (PID reuse is common on long-running machines), therefore GetProcessTreePids could graft that unrelated process into the Dynamo tree.

This is a mitigation strategy for this exact PID-recycling problem:
int candidateParentPid = pbi.InheritedFromUniqueProcessId.ToInt32();
try
{
using var parent = Process.GetProcessById(candidateParentPid);
if (parent.StartTime > process.StartTime)
{
return 0; // PID reused by an unrelated, later-started process
}
}
catch (ArgumentException)
{
return 0; // parent PID no longer refers to a running process
}
return candidateParentPid;

dynamoSandbox.Kill(entireProcessTree: true);
}
}
catch (InvalidOperationException)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This situation is low probability of ocurring, but is plausable.

Process.Kill() can throw Win32Exception in addition to InvalidOperationException.

Since the Win32Exception is uncaught inside a finally clause, .NET will replace the in-flight Exception with that new Win32Exception and the test will report a generic process-termination error instead of the list of offending connections, hiding the real failure detail.

The solution is to catch both InvalidOperationException and Win32Exception.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants