SameSite=Strict as default; closes #189

This commit is contained in:
ed 2025-07-27 18:18:49 +00:00
parent 48705a74c6
commit ca6d0b8d5e
4 changed files with 27 additions and 8 deletions

View file

@ -1288,6 +1288,7 @@ def add_stats(ap):
def add_yolo(ap):
ap2 = ap.add_argument_group('yolo options')
ap2.add_argument("--allow-csrf", action="store_true", help="disable csrf protections; let other domains/sites impersonate you through cross-site requests")
ap2.add_argument("--cookie-lax", action="store_true", help="allow cookies from other domains (if you follow a link from another website into your server, you will arrive logged-in); this reduces protection against CSRF")
ap2.add_argument("--getmod", action="store_true", help="permit ?move=[...] and ?delete as GET")
ap2.add_argument("--wo-up-readme", action="store_true", help="allow users with write-only access to upload logues and readmes without adding the _wo_ filename prefix (volflag=wo_up_readme)")

View file

@ -2995,12 +2995,20 @@ class HttpCli(object):
# reset both plaintext and tls
# (only affects active tls cookies when tls)
for k in ("cppwd", "cppws") if self.is_https else ("cppwd",):
ck = gencookie(k, pwd, self.args.R, False)
ck = gencookie(k, pwd, self.args.R, self.args.cookie_lax, False)
self.out_headerlist.append(("Set-Cookie", ck))
self.out_headers.pop("Set-Cookie", None) # drop keepalive
else:
k = "cppws" if self.is_https else "cppwd"
ck = gencookie(k, pwd, self.args.R, self.is_https, dur, "; HttpOnly")
ck = gencookie(
k,
pwd,
self.args.R,
self.args.cookie_lax,
self.is_https,
dur,
"; HttpOnly",
)
self.out_headers["Set-Cookie"] = ck
return dur > 0, msg
@ -5041,7 +5049,7 @@ class HttpCli(object):
def setck(self) -> bool:
k, v = self.uparam["setck"].split("=", 1)
t = 0 if v in ("", "x") else 86400 * 299
ck = gencookie(k, v, self.args.R, False, t)
ck = gencookie(k, v, self.args.R, self.args.cookie_lax, False, t)
self.out_headerlist.append(("Set-Cookie", ck))
if "cc" in self.ouparam:
self.redirect("", "?h#cc")
@ -5053,7 +5061,7 @@ class HttpCli(object):
for k in ALL_COOKIES:
if k not in self.cookies:
continue
cookie = gencookie(k, "x", self.args.R, False)
cookie = gencookie(k, "x", self.args.R, self.args.cookie_lax, False)
self.out_headerlist.append(("Set-Cookie", cookie))
self.redirect("", "?h#cc")

View file

@ -2037,15 +2037,25 @@ def formatdate(ts: Optional[float] = None) -> str:
return RFC2822 % (WKDAYS[wd], d, MONTHS[mo - 1], y, h, mi, s)
def gencookie(k: str, v: str, r: str, tls: bool, dur: int = 0, txt: str = "") -> str:
def gencookie(
k: str, v: str, r: str, lax: bool, tls: bool, dur: int = 0, txt: str = ""
) -> str:
v = v.replace("%", "%25").replace(";", "%3B")
if dur:
exp = formatdate(time.time() + dur)
else:
exp = "Fri, 15 Aug 1997 01:00:00 GMT"
t = "%s=%s; Path=/%s; Expires=%s%s%s; SameSite=Lax"
return t % (k, v, r, exp, "; Secure" if tls else "", txt)
t = "%s=%s; Path=/%s; Expires=%s%s%s; SameSite=%s"
return t % (
k,
v,
r,
exp,
"; Secure" if tls else "",
txt,
"Lax" if lax else "Strict",
)
def humansize(sz: float, terse: bool = False) -> str:

View file

@ -143,7 +143,7 @@ class Cfg(Namespace):
def __init__(self, a=None, v=None, c=None, **ka0):
ka = {}
ex = "chpw daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz rmagic rss smb srch_dbg srch_excl stats uqe vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
ex = "chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz rmagic rss smb srch_dbg srch_excl stats uqe vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
ka.update(**{k: False for k in ex.split()})
ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump re_dhash see_dots plain_ip"