Refined urltokens and XSRF protection
authorSteven Barth <steven@midlink.org>
Mon, 15 Dec 2008 10:40:45 +0000 (10:40 +0000)
committerSteven Barth <steven@midlink.org>
Mon, 15 Dec 2008 10:40:45 +0000 (10:40 +0000)
libs/web/luasrc/dispatcher.lua
modules/admin-full/luasrc/controller/admin/index.lua
modules/admin-mini/luasrc/controller/mini/index.lua
modules/rpc/luasrc/controller/rpc.lua

index 1fbdb7150ccf4a2a3f2d72a486128911a2ce42b3..33b95840a8632f36718c8e49df720475486ebe9f 100644 (file)
@@ -47,7 +47,12 @@ local fi
 -- @param ...  Virtual path
 -- @return             Relative 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
 
 --- 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()
        local ctx = context
        ctx.path = request
-       ctx.scriptname = luci.http.getenv("SCRIPT_NAME") or ""
        ctx.urltoken   = ctx.urltoken or {}
 
        require "luci.i18n".setlanguage(require "luci.config".main.lang)
@@ -174,11 +178,6 @@ function dispatch(request)
                end
        end
 
-       for k, v in pairs(token) do
-               ctx.scriptname = ctx.scriptname .. "/;" .. k .. "=" ..
-                       http.urlencode(v)
-       end
-
        ctx.path = preq
 
        if track.i18n then
@@ -202,9 +201,9 @@ function dispatch(request)
 
                local viewns = setmetatable({}, {__index=function(table, key)
                        if key == "controller" then
-                               return ctx.scriptname
+                               return build_url()
                        elseif key == "REQUEST_URI" then
-                               return ctx.scriptname .. "/" .. table.concat(ctx.requested, "/")
+                               return build_url(ctx.requested)
                        else
                                return rawget(table, key) or _G[key]
                        end
@@ -232,10 +231,11 @@ 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 = true
+               local verifytoken = false
                if not sess then
                        sess = luci.http.getcookie("sysauth")
                        sess = sess and sess:match("^[A-F0-9]+$")
+                       verifytoken = true
                end
 
                local sdat = sauth.read(sess)
@@ -250,12 +250,12 @@ function dispatch(request)
 
                if not util.contains(accs, user) then
                        if authen then
+                               ctx.urltoken.stok = nil
                                local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
                                if not user or not util.contains(accs, user) then
                                        return
                                else
                                        local sid = sess or luci.sys.uniqueid(16)
-                                       luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/")
                                        if not sess then
                                                local token = luci.sys.uniqueid(16)
                                                sauth.write(sid, util.get_bytecode({
@@ -263,8 +263,9 @@ function dispatch(request)
                                                        token=token,
                                                        secret=luci.sys.uniqueid(16)
                                                }))
-                                               ctx.scriptname = ctx.scriptname .. "/;stok="..token
+                                               ctx.urltoken.stok = token
                                        end
+                                       luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path="..build_url())
                                        ctx.authsession = sid
                                end
                        else
index c0322d3a2e876d19a6dca2f795737da21d6d925c..e2b812e8c35ce0b36828c882ccfe4be3df9b6a08 100644 (file)
@@ -53,8 +53,9 @@ function action_logout()
        local sauth = require "luci.sauth"
        if dsp.context.authsession then
                sauth.kill(dsp.context.authsession)
+               dsp.context.urltoken.stok = nil
        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())
 end
\ No newline at end of file
index dad6ccfab3db10ffdefafc2a1954fcb0fb8d9b03..acff55aabb8fd15655ae625f6f7088f97517e830 100644 (file)
@@ -44,8 +44,9 @@ function action_logout()
        local sauth = require "luci.sauth"
        if dsp.context.authsession then
                sauth.kill(dsp.context.authsession)
+               dsp.context.urltoken.stok = nil
        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())
 end
\ No newline at end of file
index d83c26d45501e7421f1fb6c12926181f79467191..e0aeb3bf04a1f9681fe90d13d0245b0be4dec48d 100644 (file)
@@ -25,7 +25,8 @@ function index()
        local function authenticator(validator, accs)
                local auth = luci.http.formvalue("auth", true)
                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
                                return user, auth
                        end