bug#81657: 32.0.50; url-cookie doesn't permit empty domains for cookies
"Tyler Smith" <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
Eww uses the url-cookie.el library to manage cookies, and this file
doesn't allow for cookies that set an empty domain value. Steps to
reproduce and a (naive) fix below:
To reproduce:
- Browse to the site https://kagi.com/login using the eww browser
- Enter name and password, and submit
- EWW displays a '403 Forbidden' warning and I am not logged into the
site. This is due to the session cookie not being set.
Further discussion of this issue is reported here:
https://kagifeedback.org/d/8055-kagi-search-unable-to-login-using-eww-browser/11
To fix:
I did some investigating, and found that url-cookie explicitly rejects
cookies with a domain set to the empty string "". This is hard-coded in
the following function:
(defun url-cookie-host-can-set-p (host domain)
(cond
((string= host domain) ; Apparently netscape lets you do this
t)
((zerop (length domain))
nil)
(t
;; Remove the dot from wildcard domains before matching.
(when (eq ?. (aref domain 0))
(setq domain (substring domain 1)))
(and (url-domsuf-cookie-allowed-p domain)
(string-suffix-p domain host 'ignore-case)))))
Changing the `zerop` clause to return `t` (or maybe just removing it
entirely?) allows the site to set the cookie. However, storing a cookie
with an empty domain causes problems elsewhere, as the code that
retrieves cookies expects each cookie to have a non-empty domain
set. This can be fixed by modifying the url-cookie-handle-set-cookie
function to use the host value for cookies that set an empty domain.
This is already done in cases where the domain is missing entirely, not
just empty.
(defun url-cookie-handle-set-cookie (str)
(setq url-cookies-changed-since-last-save t)
(let* ((args (nreverse (url-parse-args str t)))
(case-fold-search t)
(secure (and (assoc-string "secure" args t) t))
(domain (or (cdr-safe (assoc-string "domain" args t))
(url-host url-current-object)))
(current-url (url-view-url t))
(trusted url-cookie-trusted-urls)
(untrusted url-cookie-untrusted-urls)
(max-age (cdr-safe (assoc-string "max-age" args t)))
(localpart (or (cdr-safe (assoc-string "path" args t))
(file-name-directory
(url-filename url-current-object))))
(expires nil))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; swap in the host in place of empty domains ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (string= domain "")
(setq domain (url-host url-current-object)))
(if (and max-age (string-match "\\`-?[0-9]+\\'" max-age))
(setq expires (ignore-errors
(format-time-string "%a %b %d %H:%M:%S %Y GMT"
(time-add nil (read max-age))
t)))
(setq expires (cdr-safe (assoc-string "expires" args t))))
(while (consp trusted)
(if (string-match (car trusted) current-url)
(setq trusted (- (match-end 0) (match-beginning 0)))
(pop trusted)))
(while (consp untrusted)
(if (string-match (car untrusted) current-url)
(setq untrusted (- (match-end 0) (match-beginning 0)))
(pop untrusted)))
(and trusted untrusted
;; Choose the more specific match.
(if (> trusted untrusted) (setq untrusted nil) (setq trusted nil)))
(cond
(untrusted
;; The site was explicitly marked as untrusted by the user.
nil)
((or (eq url-privacy-level 'paranoid)
(and (listp url-privacy-level) (memq 'cookies url-privacy-level)))
;; User never wants cookies.
nil)
((and url-cookie-confirmation
(not trusted)
(save-window-excursion
(with-output-to-temp-buffer "*Cookie Warning*"
(princ (format "%s=\"%s\"\n" (caar args) (cdar args)))
(dolist (x (cdr args))
(princ (format " %s=\"%s\"\n" (car x) (cdr x)))))
(prog1
(not (funcall url-confirmation-func
(format "Allow %s to set these cookies? "
(url-host url-current-object))))
(if (get-buffer "*Cookie Warning*")
(kill-buffer "*Cookie Warning*")))))
;; User wants to be asked, and declined.
nil)
((url-cookie-host-can-set-p (url-host url-current-object) domain)
;; Cookie is accepted by the user, and passes our security checks.
(url-cookie-store (caar args) (cdar args)
expires domain localpart secure))
(t
(url-lazy-message "%s tried to set a cookie for domain %s - rejected."
(url-host url-current-object) domain)))))
This solves the problem for me, but I'm not familiar with EWW, url et al
so don't know if this is a good general solution.
Thanks,
- tyler
In GNU Emacs 32.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.41, cairo version 1.18.0) of 2026-05-11 built on
ONOTTRA825833PL.agr.gc.ca
Repository revision: 66729f3e5080f8853393e5f88ce6f062b45164b7
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101011
System Description: Ubuntu 24.04.4 LTS
Configured using:
'configure --without-compress-install --with-native-compilation
--with-mailutils --with-tree-sitter'
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINERAMA XINPUT2 XPM
XRANDR GTK3 ZLIB
Important settings:
value of $LANG: en_US.UTF-8
value of $XMODIFIERS: @im=ibus
locale-coding-system: utf-8-unix
Major mode: eww
Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
minibuffer-nonselected-mode: t
minibuffer-regexp-mode: t
buffer-read-only: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
None found.
Features:
(shadow sort mail-extr compile comint ansi-osc ansi-color ring emacsbug
lisp-mnt message yank-media dired dired-loaddefs rfc822 mml mml-sec epa
derived epg rfc6068 epg-config mm-decode mm-bodies mm-encode mailabbrev
gmm-utils mailheader sendmail textsec uni-scripts idna-mapping
ucs-normalize uni-confusable textsec-check cl-extra help-mode gnutls
network-stream url-http mail-parse rfc2231 rfc2047 rfc2045 ietf-drums
url-gw nsm url-cache url-auth format-spec comp-run bytecomp byte-compile
comp-common rx eww track-changes vtable url-queue thingatpt shr
pixel-fill kinsoku url-file svg xml dom browse-url xdg url url-proxy
url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util url-parse auth-source cl-seq
eieio eieio-core cl-macs gv icons password-cache json map url-vars
mailcap puny mm-url gnus nnheader gnus-util text-property-search
time-date subr-x mule-util mail-utils range wid-edit mm-util mail-prsvr
cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren electric
uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo gtk
x-toolkit xinput2 x multi-tty move-toolbar make-network-process
tty-child-frames native-compile emacs)
Memory information:
((conses 16 259613 15265) (symbols 48 11442 0) (strings 32 47271 2763)
(string-bytes 1 1159997) (vectors 16 40073)
(vector-slots 8 540489 19471) (floats 8 70 278)
(intervals 56 1319 193) (buffers 1064 14))
--
plantarum.ca