Skip to content

Commit

Permalink
luci-base: remove security token from urls
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jow- committed Oct 20, 2015
1 parent f23f7b8 commit 86326e0
Showing 1 changed file with 14 additions and 38 deletions.
52 changes: 14 additions & 38 deletions modules/luci-base/luasrc/dispatcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand All @@ -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")
Expand Down Expand Up @@ -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)))
Expand All @@ -403,6 +378,7 @@ function dispatch(request)
end
else
ctx.authsession = sess
ctx.authtoken = token
ctx.authuser = user
end
end
Expand All @@ -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
Expand Down

0 comments on commit 86326e0

Please sign in to comment.