Preserve cookie security attributes in updateCookies round-trip
Chromium's Cookies() API can lose or normalize Secure, SameSite, and HttpOnly attributes during the AddCookies → navigate → Cookies() round-trip. This caused cookies like cf_clearance (set with Secure=true, SameSite=None) to be overwritten with Chromium's defaults (Secure=false, SameSite=Lax). Now updateCookies() looks up existing cookies in the jar first. For cookies that already exist, only Value and Expires are updated — security attributes are preserved from the original. New cookies from the server are still written with all their attributes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -219,11 +219,35 @@ func (b playWrightBrowser) updateCookies(_ context.Context, page playwright.Page
|
||||
return fmt.Errorf("error getting cookies from browser: %w", err)
|
||||
}
|
||||
|
||||
// Build a lookup of existing cookies so we can preserve their security
|
||||
// attributes. Chromium's Cookies() API can lose or normalize Secure,
|
||||
// SameSite, and HttpOnly during the AddCookies → navigate → Cookies()
|
||||
// round-trip, so we only update Value and Expires for cookies that
|
||||
// already exist in the jar.
|
||||
existing, err := b.cookieJar.Get(page.URL())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting existing cookies from jar: %w", err)
|
||||
}
|
||||
type cookieKey struct{ Name, Path string }
|
||||
existingMap := make(map[cookieKey]Cookie, len(existing))
|
||||
for _, c := range existing {
|
||||
existingMap[cookieKey{c.Name, c.Path}] = c
|
||||
}
|
||||
|
||||
for _, cookie := range cookies {
|
||||
// TODO: add support for deleting cookies from the jar which are deleted in the browser
|
||||
err = b.cookieJar.Set(playwrightCookieToCookie(cookie))
|
||||
c := playwrightCookieToCookie(cookie)
|
||||
|
||||
if err != nil {
|
||||
if prev, ok := existingMap[cookieKey{c.Name, c.Path}]; ok {
|
||||
// Preserve the original security attributes; only update
|
||||
// Value and Expires which are the fields that legitimately
|
||||
// change during navigation.
|
||||
c.Secure = prev.Secure
|
||||
c.HttpOnly = prev.HttpOnly
|
||||
c.SameSite = prev.SameSite
|
||||
}
|
||||
|
||||
if err = b.cookieJar.Set(c); err != nil {
|
||||
return fmt.Errorf("error setting cookie in cookie jar: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user