Refined urltokens and XSRF protection

This commit is contained in:
Steven Barth 2008-12-15 10:40:45 +00:00
parent 73109f3e46
commit 1ee5ba632a
4 changed files with 19 additions and 15 deletions

View file

@ -47,7 +47,12 @@ local fi
-- @param ... Virtual path -- @param ... Virtual path
-- @return Relative URL -- @return Relative URL
function build_url(...) function build_url(...)
return context.scriptname .. "/" .. table.concat(arg, "/") local path = {...}
local sn = http.getenv("SCRIPT_NAME") or ""
for k, v in pairs(context.urltoken) do
sn = sn .. "/;" .. k .. "=" .. http.urlencode(v)
end
return sn .. ((#path > 0) and "/" .. table.concat(path, "/") or "")
end end
--- Send a 404 error code and render the "error404" template if available. --- Send a 404 error code and render the "error404" template if available.
@ -123,7 +128,6 @@ function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace() --context._disable_memtrace = require "luci.debug".trap_memtrace()
local ctx = context local ctx = context
ctx.path = request ctx.path = request
ctx.scriptname = luci.http.getenv("SCRIPT_NAME") or ""
ctx.urltoken = ctx.urltoken or {} ctx.urltoken = ctx.urltoken or {}
require "luci.i18n".setlanguage(require "luci.config".main.lang) require "luci.i18n".setlanguage(require "luci.config".main.lang)
@ -174,11 +178,6 @@ function dispatch(request)
end end
end end
for k, v in pairs(token) do
ctx.scriptname = ctx.scriptname .. "/;" .. k .. "=" ..
http.urlencode(v)
end
ctx.path = preq ctx.path = preq
if track.i18n then if track.i18n then
@ -202,9 +201,9 @@ function dispatch(request)
local viewns = setmetatable({}, {__index=function(table, key) local viewns = setmetatable({}, {__index=function(table, key)
if key == "controller" then if key == "controller" then
return ctx.scriptname return build_url()
elseif key == "REQUEST_URI" then elseif key == "REQUEST_URI" then
return ctx.scriptname .. "/" .. table.concat(ctx.requested, "/") return build_url(ctx.requested)
else else
return rawget(table, key) or _G[key] return rawget(table, key) or _G[key]
end end
@ -232,10 +231,11 @@ function dispatch(request)
local def = (type(track.sysauth) == "string") and track.sysauth local def = (type(track.sysauth) == "string") and track.sysauth
local accs = def and {track.sysauth} or track.sysauth local accs = def and {track.sysauth} or track.sysauth
local sess = ctx.authsession local sess = ctx.authsession
local verifytoken = true local verifytoken = false
if not sess then if not sess then
sess = luci.http.getcookie("sysauth") sess = luci.http.getcookie("sysauth")
sess = sess and sess:match("^[A-F0-9]+$") sess = sess and sess:match("^[A-F0-9]+$")
verifytoken = true
end end
local sdat = sauth.read(sess) local sdat = sauth.read(sess)
@ -250,12 +250,12 @@ function dispatch(request)
if not util.contains(accs, user) then if not util.contains(accs, user) then
if authen then if authen then
ctx.urltoken.stok = nil
local user, sess = authen(luci.sys.user.checkpasswd, accs, def) local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
if not user or not util.contains(accs, user) then if not user or not util.contains(accs, user) then
return return
else else
local sid = sess or luci.sys.uniqueid(16) local sid = sess or luci.sys.uniqueid(16)
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/")
if not sess then if not sess then
local token = luci.sys.uniqueid(16) local token = luci.sys.uniqueid(16)
sauth.write(sid, util.get_bytecode({ sauth.write(sid, util.get_bytecode({
@ -263,8 +263,9 @@ function dispatch(request)
token=token, token=token,
secret=luci.sys.uniqueid(16) secret=luci.sys.uniqueid(16)
})) }))
ctx.scriptname = ctx.scriptname .. "/;stok="..token ctx.urltoken.stok = token
end end
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path="..build_url())
ctx.authsession = sid ctx.authsession = sid
end end
else else

View file

@ -53,8 +53,9 @@ function action_logout()
local sauth = require "luci.sauth" local sauth = require "luci.sauth"
if dsp.context.authsession then if dsp.context.authsession then
sauth.kill(dsp.context.authsession) sauth.kill(dsp.context.authsession)
dsp.context.urltoken.stok = nil
end end
luci.http.header("Set-Cookie", "sysauth=; path=/") luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
luci.http.redirect(luci.dispatcher.build_url()) luci.http.redirect(luci.dispatcher.build_url())
end end

View file

@ -44,8 +44,9 @@ function action_logout()
local sauth = require "luci.sauth" local sauth = require "luci.sauth"
if dsp.context.authsession then if dsp.context.authsession then
sauth.kill(dsp.context.authsession) sauth.kill(dsp.context.authsession)
dsp.context.urltoken.stok = nil
end end
luci.http.header("Set-Cookie", "sysauth=; path=/") luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
luci.http.redirect(luci.dispatcher.build_url()) luci.http.redirect(luci.dispatcher.build_url())
end end

View file

@ -25,7 +25,8 @@ function index()
local function authenticator(validator, accs) local function authenticator(validator, accs)
local auth = luci.http.formvalue("auth", true) local auth = luci.http.formvalue("auth", true)
if auth then if auth then
local user = luci.sauth.read(auth) local sdat = luci.sauth.read(auth)
user = loadstring(sdat)().user
if user and luci.util.contains(accs, user) then if user and luci.util.contains(accs, user) then
return user, auth return user, auth
end end