luci-base: add FULL_REQUEST_URI template property
authorJo-Philipp Wich <jo@mein.io>
Wed, 4 Apr 2018 21:24:31 +0000 (23:24 +0200)
committerJo-Philipp Wich <jo@mein.io>
Wed, 4 Apr 2018 21:24:31 +0000 (23:24 +0200)
Introduce a new template property FULL_REQUEST_URI which returns the full
canonicalized request URL built from SCRIPT_NAME, PATH_INFO and QUERY_STRING.

This new property is safer to use compared to using the raw REQUEST_URI CGI
environment variable directly as this value is essentially untrusted user
input which may contain embedded escaped slashes, double forward slashes and
other oddities allowing XSS exploitation or request redirection.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/luasrc/dispatcher.lua

index 16b32548e6f626b2928cb6b2589e26947494085d..24681368d708a6d184149ba796fb84f58ae55c5c 100644 (file)
@@ -346,15 +346,23 @@ function dispatch(request)
                   ifattr      = function(...) return _ifattr(...) end;
                   attr        = function(...) return _ifattr(true, ...) end;
                   url         = build_url;
-               }, {__index=function(table, key)
+               }, {__index=function(tbl, key)
                        if key == "controller" then
                                return build_url()
                        elseif key == "REQUEST_URI" then
                                return build_url(unpack(ctx.requestpath))
+                       elseif key == "FULL_REQUEST_URI" then
+                               local url = { http.getenv("SCRIPT_NAME"), http.getenv("PATH_INFO") }
+                               local query = http.getenv("QUERY_STRING")
+                               if query and #query > 0 then
+                                       url[#url+1] = "?"
+                                       url[#url+1] = query
+                               end
+                               return table.concat(url, "")
                        elseif key == "token" then
                                return ctx.authtoken
                        else
-                               return rawget(table, key) or _G[key]
+                               return rawget(tbl, key) or _G[key]
                        end
                end})
        end