summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2015-10-20 20:58:30 +0200
committerJo-Philipp Wich <jow@openwrt.org>2015-10-20 21:04:46 +0200
commit562c47e5fd73bacc314f561592ad1b4ce8b8dc48 (patch)
treefc92e5e5d539e28f3746a55bc326dbabbff05a4e
parente8349fbfdf5de82ba3f3e9d147c0ddfa31c2293c (diff)
luci-base: generalize post security token handling
* Add a generic helper function to check need for post / csrf token validation * Remove custom token verification in cbi targets * Support requiring post security depending on specific submit parameters, usable through post_on() action Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua69
1 files changed, 46 insertions, 23 deletions
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index 5d9d1b0b1a..df562dd5da 100644
--- a/modules/luci-base/luasrc/dispatcher.lua
+++ b/modules/luci-base/luasrc/dispatcher.lua
@@ -174,6 +174,32 @@ function httpdispatch(request, prefix)
--context._disable_memtrace()
end
+local function require_post_security(target)
+ if type(target) == "table" then
+ if type(target.post) == "table" then
+ local param_name, required_val, request_val
+
+ for param_name, required_val in pairs(target.post) do
+ request_val = http.formvalue(param_name)
+
+ if (type(required_val) == "string" and
+ request_val ~= required_val) or
+ (required_val == true and
+ (request_val == nil or request_val == ""))
+ then
+ return false
+ end
+ end
+
+ return true
+ end
+
+ return (target.post == true)
+ end
+
+ return false
+end
+
function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace("l")
local ctx = context
@@ -381,7 +407,7 @@ function dispatch(request)
end
end
- if c and type(c.target) == "table" and c.target.post == true then
+ if c and require_post_security(c.target) then
if http.getenv("REQUEST_METHOD") ~= "POST" then
http.status(405, "Method Not Allowed")
http.header("Allow", "POST")
@@ -720,16 +746,20 @@ function call(name, ...)
return {type = "call", argv = {...}, name = name, target = _call}
end
-function post(name, ...)
+function post_on(params, name, ...)
return {
type = "call",
- post = true,
+ post = params,
argv = { ... },
name = name,
target = _call
}
end
+function post(...)
+ return post_on(true, ...)
+end
+
local _template = function(self, ...)
require "luci.template".render(self.view)
@@ -744,15 +774,6 @@ local function _cbi(self, ...)
local cbi = require "luci.cbi"
local tpl = require "luci.template"
local http = require "luci.http"
- local disp = require "luci.dispatcher"
-
- if http.formvalue("cbi.submit") == "1" and
- http.formvalue("token") ~= disp.context.urltoken.stok
- then
- http.status(403, "Forbidden")
- luci.template.render("csrftoken")
- return
- end
local config = self.config or {}
local maps = cbi.load(self.model, ...)
@@ -850,7 +871,13 @@ local function _cbi(self, ...)
end
function cbi(model, config)
- return {type = "cbi", config = config, model = model, target = _cbi}
+ return {
+ type = "cbi",
+ post = { ["cbi.submit"] = "1" },
+ config = config,
+ model = model,
+ target = _cbi
+ }
end
@@ -870,15 +897,6 @@ local function _form(self, ...)
local cbi = require "luci.cbi"
local tpl = require "luci.template"
local http = require "luci.http"
- local disp = require "luci.dispatcher"
-
- if http.formvalue("cbi.submit") == "1" and
- http.formvalue("token") ~= disp.context.urltoken.stok
- then
- http.status(403, "Forbidden")
- luci.template.render("csrftoken")
- return
- end
local maps = luci.cbi.load(self.model, ...)
local state = nil
@@ -899,7 +917,12 @@ local function _form(self, ...)
end
function form(model)
- return {type = "cbi", model = model, target = _form}
+ return {
+ type = "cbi",
+ post = { ["cbi.submit"] = "1" },
+ model = model,
+ target = _form
+ }
end
translate = i18n.translate