From 08fb38399f5b297be7d460703b70d3b893139f9f Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 8 Jul 2022 15:38:53 +0200 Subject: [PATCH] luci-base: use different cookie names for HTTP and HTTPS Since HTTP cookies may not overwrite HTTPS ("secure") ones, users are frequently unable to log into LuCI when a stale, "secure" `sysauth` cookie is still present in the browser as it commonly happens after e.g. a sysupgrade operation or when frequently jumping between HTTP and HTTPS access. Rework the dispatcher to set either a `sysauth_http` or `sysauth_https` cookie, depending on the HTTPS state of the server connection and accept both cookie names when verifying the session ID. This allows users to log into a HTTP-only LuCI instance while a stale, "secure" HTTPS cookie is still present. Requires commit 2b0539ef9d ("lucihttp: update to latest Git HEAD") to function properly. Fixes: #5843 Signed-off-by: Jo-Philipp Wich (cherry picked from commit e1932592c3e0804eec5d85fee989ceeed1e1050a) --- modules/luci-base/luasrc/controller/admin/index.lua | 13 ++++++++----- modules/luci-base/luasrc/dispatcher.lua | 9 +++++---- .../root/usr/share/luci/menu.d/luci-base.json | 6 +++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/luci-base/luasrc/controller/admin/index.lua b/modules/luci-base/luasrc/controller/admin/index.lua index 736d0cdccff3..8f9b481ccef2 100644 --- a/modules/luci-base/luasrc/controller/admin/index.lua +++ b/modules/luci-base/luasrc/controller/admin/index.lua @@ -11,9 +11,13 @@ function action_logout() if sid then utl.ubus("session", "destroy", { ubus_rpc_session = sid }) - luci.http.header("Set-Cookie", "sysauth=%s; expires=%s; path=%s" %{ - '', 'Thu, 01 Jan 1970 01:00:00 GMT', dsp.build_url() - }) + local url = dsp.build_url() + + if luci.http.getenv('HTTPS') == 'on' then + luci.http.header("Set-Cookie", "sysauth_https=; expires=Thu, 01 Jan 1970 01:00:00 GMT; path=%s" % url) + end + + luci.http.header("Set-Cookie", "sysauth_http=; expires=Thu, 01 Jan 1970 01:00:00 GMT; path=%s" % url) end luci.http.redirect(dsp.build_url()) @@ -185,10 +189,9 @@ end function action_menu() local dsp = require "luci.dispatcher" - local utl = require "luci.util" local http = require "luci.http" - local acls = utl.ubus("session", "access", { ubus_rpc_session = http.getcookie("sysauth") }) + local _, _, acls = dsp.is_authenticated({ methods = { "cookie:sysauth_https", "cookie:sysauth_http" } }) local menu = dsp.menu_json(acls or {}) or {} http.prepare_content("application/json") diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index d27af0755afd..a3726fb1c11d 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -343,12 +343,12 @@ local function tree_to_json(node, json) if subnode.sysauth_authenticator == "htmlauth" then spec.auth = { login = true, - methods = { "cookie:sysauth" } + methods = { "cookie:sysauth_https", "cookie:sysauth_http" } } elseif subname == "rpc" and subnode.module == "luci.controller.rpc" then spec.auth = { login = false, - methods = { "query:auth", "cookie:sysauth" } + methods = { "query:auth", "cookie:sysauth_https", "cookie:sysauth_http" } } elseif subnode.module == "luci.controller.admin.uci" then spec.auth = { @@ -732,7 +732,7 @@ local function init_template_engine(ctx) return tpl end -local function is_authenticated(auth) +function is_authenticated(auth) if type(auth) == "table" and type(auth.methods) == "table" and #auth.methods > 0 then local sid, sdat, sacl for _, method in ipairs(auth.methods) do @@ -929,7 +929,8 @@ function dispatch(request) return tpl.render("sysauth", scope) end - http.header("Set-Cookie", 'sysauth=%s; path=%s; SameSite=Strict; HttpOnly%s' %{ + http.header("Set-Cookie", 'sysauth_%s=%s; path=%s; SameSite=Strict; HttpOnly%s' %{ + http.getenv("HTTPS") == "on" and "https" or "http", sid, build_url(), http.getenv("HTTPS") == "on" and "; secure" or "" }) diff --git a/modules/luci-base/root/usr/share/luci/menu.d/luci-base.json b/modules/luci-base/root/usr/share/luci/menu.d/luci-base.json index 2a99684c2ce0..605c7ab77723 100644 --- a/modules/luci-base/root/usr/share/luci/menu.d/luci-base.json +++ b/modules/luci-base/root/usr/share/luci/menu.d/luci-base.json @@ -7,7 +7,7 @@ "recurse": true }, "auth": { - "methods": [ "cookie:sysauth" ], + "methods": [ "cookie:sysauth_https", "cookie:sysauth_http" ], "login": true } }, @@ -115,7 +115,7 @@ "post": true }, "auth": { - "methods": [ "cookie:sysauth" ] + "methods": [ "cookie:sysauth_https", "cookie:sysauth_http" ] } }, @@ -128,7 +128,7 @@ "post": true }, "auth": { - "methods": [ "cookie:sysauth" ] + "methods": [ "cookie:sysauth_https", "cookie:sysauth_http" ] } },