Check paired origins at every intercepted request
2 files changed,
+40
−4
internal/home/browser_driver_boundaries_test.go+35 −4scripts/credential-browser.mjs+5 −0
CI passed — run details
diff --git a/internal/home/browser_driver_boundaries_test.go b/internal/home/browser_driver_boundaries_test.go| index 9c1aef3..4e6fcd5 100644 |
| --- a/internal/home/browser_driver_boundaries_test.go |
| +++ b/internal/home/browser_driver_boundaries_test.go |
| @@ -52,7 +52,7 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| if runtime.GOOS != "linux" { |
| t.Skip() |
| } |
| - for _, mode := range []string{"redirect307", "redirect308", "repeat", "pending-mail-cancel"} { |
| + for _, mode := range []string{"external307", "external308", "redirect307", "redirect308", "repeat", "pending-mail-cancel"} { |
| t.Run(mode, func(t *testing.T) { |
| origins := Origins{"https://id.home-browser.test", "https://directory.home-browser.test"} |
| app := newTestAppWithOrigins(t, origins) |
| @@ -64,6 +64,17 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| } |
| var mu sync.Mutex |
| posts := 0 |
| + thirdRequests := 0 |
| + third := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| + mu.Lock() |
| + thirdRequests++ |
| + mu.Unlock() |
| + w.WriteHeader(http.StatusOK) |
| + })) |
| + third.Config.ErrorLog = log.New(io.Discard, "", 0) |
| + third.StartTLS() |
| + defer third.Close() |
| + thirdURL := strings.Replace(third.URL, "127.0.0.1", "localhost", 1) |
| pending := make(chan struct{}) |
| var once sync.Once |
| server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| @@ -76,6 +87,14 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| posts++ |
| mu.Unlock() |
| once.Do(func() { close(pending) }) |
| + if strings.HasPrefix(mode, "external") { |
| + status := 307 |
| + if mode == "external308" { |
| + status = 308 |
| + } |
| + http.Redirect(w, r, thirdURL+"/signin", status) |
| + return |
| + } |
| if strings.HasPrefix(mode, "redirect") { |
| status := 307 |
| if mode == "redirect308" { |
| @@ -94,6 +113,9 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| rec := httptest.NewRecorder() |
| router.ServeHTTP(rec, r) |
| for k, values := range rec.Header() { |
| + if strings.HasPrefix(mode, "external") && strings.EqualFold(k, "Content-Security-Policy") { |
| + continue |
| + } |
| w.Header()[k] = values |
| } |
| w.WriteHeader(rec.Code) |
| @@ -142,12 +164,16 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| chromium++ |
| } |
| } |
| - if chromium == 0 { |
| + if chromium == 0 && !strings.HasPrefix(mode, "external") { |
| cancel() |
| <-finished |
| t.Fatal("no Chromium descendants observed") |
| } |
| - time.Sleep(300 * time.Millisecond) |
| + if strings.HasPrefix(mode, "external") { |
| + time.Sleep(1500 * time.Millisecond) |
| + } else { |
| + time.Sleep(300 * time.Millisecond) |
| + } |
| cancel() |
| select { |
| case <-finished: |
| @@ -174,8 +200,13 @@ func TestBrowserDriverOutgoingBudgetAndCancellation(t *testing.T) { |
| } |
| mu.Lock() |
| actual := posts |
| + thirdActual := thirdRequests |
| mu.Unlock() |
| - if mode == "pending-mail-cancel" { |
| + if strings.HasPrefix(mode, "external") { |
| + if actual != 1 || thirdActual != 0 { |
| + t.Fatalf("signin POSTs=%d third-host requests=%d", actual, thirdActual) |
| + } |
| + } else if mode == "pending-mail-cancel" { |
| if actual != 1 { |
| t.Fatalf("pending-mail POST count=%d", actual) |
| } |
diff --git a/scripts/credential-browser.mjs b/scripts/credential-browser.mjs| index 6ab5408..2481bdb 100644 |
| --- a/scripts/credential-browser.mjs |
| +++ b/scripts/credential-browser.mjs |
| @@ -76,6 +76,11 @@ try { |
| cdp.on('Fetch.requestPaused', async event => { |
| try { |
| const url = new URL(event.request.url); |
| + if (![credential.origin, directory.origin].includes(url.origin) || (event.request.method === 'POST' && !verified)) { |
| + external = true; |
| + await cdp.send('Fetch.failRequest', { requestId: event.requestId, errorReason: 'Aborted' }); |
| + return; |
| + } |
| if (event.request.method === 'POST' && url.pathname === '/signin') { |
| if (!verified || signinPosts >= 4) { |
| budgetExceeded = true; |