luci-base: remove security token from urls

Now that sensitive urls require post requests and only accept them if a valid
security token is sent along the request, we can drop the global random url
token to improve LuCI usability.

The main improvement is the ability to use multiple tabs with the same login
session, but also deep linking to specific urls without the need for another
login becomes feasible, e.g. for documentation purposes.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
This commit is contained in:
Jo-Philipp Wich 2015-10-21 00:31:27 +02:00
parent f23f7b8751
commit 86326e0def

View file

@ -113,24 +113,11 @@ function authenticator.htmlauth(validator, accs, default)
return user
end
if context.urltoken.stok then
context.urltoken.stok = nil
local cookie = 'sysauth=%s; expires=%s; path=%s/' %{
http.getcookie('sysauth') or 'x',
'Thu, 01 Jan 1970 01:00:00 GMT',
build_url()
}
http.header("Set-Cookie", cookie)
http.redirect(build_url())
else
require("luci.i18n")
require("luci.template")
context.path = {}
http.status(403, "Forbidden")
luci.template.render("sysauth", {duser=default, fuser=user})
end
require("luci.i18n")
require("luci.template")
context.path = {}
http.status(403, "Forbidden")
luci.template.render("sysauth", {duser=default, fuser=user})
return false
@ -151,18 +138,8 @@ function httpdispatch(request, prefix)
end
end
local tokensok = true
for node in pathinfo:gmatch("[^/]+") do
local tkey, tval
if tokensok then
tkey, tval = node:match(";(%w+)=([a-fA-F0-9]*)")
end
if tkey then
context.urltoken[tkey] = tval
else
tokensok = false
r[#r+1] = node
end
r[#r+1] = node
end
local stat, err = util.coxpcall(function()
@ -311,13 +288,14 @@ function dispatch(request)
resource = luci.config.main.resourcebase;
ifattr = function(...) return _ifattr(...) end;
attr = function(...) return _ifattr(true, ...) end;
token = ctx.urltoken.stok;
url = build_url;
}, {__index=function(table, key)
if key == "controller" then
return build_url()
elseif key == "REQUEST_URI" then
return build_url(unpack(ctx.requestpath))
elseif key == "token" then
return ctx.authtoken
else
return rawget(table, key) or _G[key]
end
@ -340,20 +318,17 @@ function dispatch(request)
local def = (type(track.sysauth) == "string") and track.sysauth
local accs = def and {track.sysauth} or track.sysauth
local sess = ctx.authsession
local verifytoken = false
if not sess then
sess = http.getcookie("sysauth")
sess = sess and sess:match("^[a-f0-9]*$")
verifytoken = true
end
local sdat = (util.ubus("session", "get", { ubus_rpc_session = sess }) or { }).values
local user
local user, token
if sdat then
if not verifytoken or ctx.urltoken.stok == sdat.token then
user = sdat.user
end
user = sdat.user
token = sdat.token
else
local eu = http.getenv("HTTP_AUTH_USER")
local ep = http.getenv("HTTP_AUTH_PASS")
@ -390,8 +365,8 @@ function dispatch(request)
sess, build_url()
})
ctx.urltoken.stok = token
ctx.authsession = sess
ctx.authtoken = token
ctx.authuser = user
http.redirect(build_url(unpack(ctx.requestpath)))
@ -403,6 +378,7 @@ function dispatch(request)
end
else
ctx.authsession = sess
ctx.authtoken = token
ctx.authuser = user
end
end
@ -414,7 +390,7 @@ function dispatch(request)
return
end
if http.formvalue("token") ~= ctx.urltoken.stok then
if http.formvalue("token") ~= ctx.authtoken then
http.status(403, "Forbidden")
luci.template.render("csrftoken")
return