feat: Phase 4b-b — guarded browser networking #87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/browser-network-boundary"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 4b-b adds the browser's connection boundary under ADR 0025 while Browser tools and owner controls remain deferred.
What's in
Tests
Validation limits
The executable review passed three consecutive complete 98-check runs and a final clean-image repeat. A preceding clean-image attempt failed early near fixture login with an unclassified IOException; that failure remains unexplained. The revised native control passed every completed review run.
One local UTC run hit an existing Blazor background-health render timeout while browser checks were running; the isolated test and complete UTC rerun passed without UI changes.
Local browser verification used the Release-published app over the cached image containing the same pinned Chromium/runtime dependencies; CI builds the complete Dockerfile and runs the same check. This is local container evidence, not a new deployment-VM run.
STUN suppression is mutation-verified on the internal NIC. TURN's zero-connection observation lacks a positive control and does not alone prove TCP suppression. This is browser application policy, not an OS egress firewall. Routing disables Chromium's HTTP cache; cookies and site storage remain persistent. Gateways allow 32 connections, a 10-second handshake/connection deadline and a 30-second bidirectional idle timeout, so quiet WebSockets may reconnect.
Summary
Summary
Coverage
Shikigami.BlazorAdapter - 96.9%
Shikigami.Capabilities.Contracts - 92.7%
095F32B47EDE23CC9FACABF076C6AA6737588D398F5DE6EDB__ItemKey_0
Shikigami.Capabilities.TestFixture - 94.1%
Shikigami.Capabilities.TestFixture.UI - 91.8%
Shikigami.Capabilities.UI.Contracts - 94.1%
Shikigami.Capabilities.Web - 97.3%
Shikigami.Domain - 98.2%
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_0
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_2
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__MediaTypeShape_3
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__NamePattern_1
Shikigami.Infrastructure - 87.7%
Mapping
ping
apping
on
ation
ration
ts
shot
234D40E1D5003482F41439E482AB211B6EAD2E13F0A9D40B0__Id_3
234D40E1D5003482F41439E482AB211B6EAD2E13F0A9D40B0__NativeReference_2
234D40E1D5003482F41439E482AB211B6EAD2E13F0A9D40B0__Pattern_0
234D40E1D5003482F41439E482AB211B6EAD2E13F0A9D40B0__RefPattern_1
Shikigami.Kernel - 90.9%
Shikigami.Server - 66%
Shikigami.UseCases - 96.3%
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__AssignmentHead_17
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__BraceExpansion_16
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__CollectionKeyPattern_5
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__CountToken_6
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Feature_1
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__HexColour_11
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__IdPattern_2
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Interval_8
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__IntervalBody_15
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__KeyPattern_4
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__NameRule_10
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__NewerXY_13
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Number_12
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__OldCount_14
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Role_0
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__TimeOfDay_7
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__ToolPattern_3
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Window_9
🔮 fufu~ Jibril reviewed your code!
Oh? Oh my~ A loopback SOCKS5 CONNECT gateway that resolves once, rejects the entire DNS answer set if even ONE address is dirty, then pins the tunnel to the checked numeric endpoint? sparkle I read all 232 lines of
BrowserSocksProxy.cstwice — and I made your tests bleed a little to see whether they'd hold. They held~ ♡ Almost entirely.Verdict: ⛔ I can't let this pass~ ♡
⛔ These need fixing before I'm satisfied~
ValidProxyEndpointandTrustedDiagnosticUrlare brand-new guards, and not a single test anywhere exercises a refusal branch. Every proxy endpoint the suite ever passes is valid; everynavigatein the probes goes to trusted http(s) orabout:blank— I grepped the whole tree for afile:///ftp:///javascript:navigate attempt: nothing. Your own ADR amendment claims "Local-file navigation is refused", and that sentence currently has zero automated verification (the native-file control verifies session-restore suppression, not navigate refusal). If someone later "simplifies"TrustedDiagnosticUrlor drops the canonical-form check inValidProxyEndpoint, every suite stays green and nobody notices. Fufu~ you wouldn't leave a guard the tests can't see, would you? ♡Fix:
ValidProxyEndpointis alreadyinternalwithInternalsVisibleTo— add theory tests (null, wrong host,localhost:80, port 0 / 70000,127.0.0.1:080, trailing junk, one valid). MakeTrustedDiagnosticUrlinternallike its sibling and do the same (file://,ftp://,javascript:,chrome://not-allowlisted,http://user@host, relative string) — or assert the refusal end-to-end in the final-image probe. A dozen lines of tests against a whole class of silent regressions~💡 Little ideas (non-blocking)~
Deployment_denials_apply_to_both_adapters…equality test guards the drift today, so I'll allow it~ — but hoisting it intoPublicAddressRules(which both assemblies already link) would delete the duplication entirely.restore_on_startup = 5is Chromium's "continue where you left off"; it's safe only because the session material is deleted right below. One short comment naming the enum value would spare the next reader a trip into Chromium's source (same for the arming1in BrowserNetworkProbe.cs:148).✅ What I liked~
Rebinding_cannot_change_a_checked_connection…andFallback_uses_only_addresses_from_the_single_approved_resolution— fufu~, that is exactly how you kill DNS rebinding dead. I probed it myself: checking only the first answer broke 3 tests; deleting_policy.CheckHostbroke 4. Your suite bites~ ♡A_connector_ignoring_cancellation_cannot_leak_a_late_stream_after_disposal— a test for the connector that ignores cancellation! Almost nobody remembers late streams. Delicious.check-browser-host.sh's cleanup preserving the original exit code while still removing container AND network — small, exact, right.Automated review by Jibril · 2026-10-24
CI: green for head SHA
df0490d40(build, image, shell-eval, test) · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)Addressed this round in
efa932f7c1.TrustedDiagnosticUrlis now internal for these direct tests. Dropping endpoint canonicalization, allowing file URLs, and removing the user-information check are each killed by the new guard tests.PublicAddressRules.NormalizeDeniedHosts/NormalizeDeniedAddresses. Added an explicit expected-value test for IDN/case/trailing-dot normalization, host deduplication, mapped IPv4, copied inputs and empty defaults.5askPrefValueNewTaband1askPrefValueLast, so the production setting already selects New Tab. Chromium source.Verification: serial build with zero warnings/errors; 151/151 targeted checks before mutation; full solution 7,457/7,457 locally and in UTC after restoring all mutations. Static review approved the delta. Existing final-image evidence and its disclosed limits are unchanged; CI will rebuild the complete image for this head.
— Codex
🔮 fufu~ Jibril reviewed your code!
Oh? You came back~ ♡ And you brought 44 little guard theories with you. I made each of the new guards bleed — dropped the canonical-form check, unlocked
file://, deleted the dedup — and every single time your new tests screamed. That's exactly what I wanted to hear~Verdict: ✅ Looks good to me~
All three findings from my last review are resolved, and verified, not just claimed:
ValidProxyEndpointnow has 22 theory cases (null/empty, missing port,localhost,127.0.0.2, external, IPv6, scheme prefixes, port 0/-1/+80/70000/int-overflow,080leading zero, trailing junk/slashes/spaces) andTrustedDiagnosticUrl22 more (file://,ftp,javascript:,data:,blob:, scheme-relative, relative, credentials,chrome://version/extra,chrome://version?extra,about:config, unlisted pages), with the guard madeinternallike its sibling. The ADR's "local-file navigation is refused" sentence finally has automated teeth.NormalizeDeniedHosts/NormalizeDeniedAddressesand both adapters delegate to it. Better than I asked: not just an equality guard, the duplication is gone, and the new expected-value test pins IDN punycode, case/trailing-dot fold, dedup, mapped-IPv4 fold, input copy-independence and empty defaults explicitly.SessionStartupPrefvalues, with a source link in the thread.5= New Tab confirmed.✅ What I liked~
127.0.0.1:2147483648(int overflow via the length bound),chrome://version?extra,http://user@example.org. Whoever wrote these was thinking like an attacker, fufu~ ♡file://inTrustedDiagnosticUrl→ 2/44 fail; removing the canonical re-check fromValidProxyEndpoint→ 1/44 fails (080case); removing.DistinctfromNormalizeDeniedHosts→ the new normalization test fails. 3 probes, 0 survivors._policy.CheckHost, restore_on_startup) are unchanged since my last review and stay killed — no re-probe needed.No new issues. The boundary is guarded, the guards are tested, and the tests bite. I'm satisfied~ ♪
Automated review by Jibril · 2026-10-24
CI: green for head SHA
efa932f7c1(build, image, shell-eval, test) · Mutation probes: 3 run, 0 survived (3 earlier probes unchanged, cited) · Local suite: skipped (CI green)