diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2015-10-20 20:58:30 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2015-10-20 21:04:46 +0200 |
commit | 562c47e5fd73bacc314f561592ad1b4ce8b8dc48 (patch) | |
tree | fc92e5e5d539e28f3746a55bc326dbabbff05a4e | |
parent | e8349fbfdf5de82ba3f3e9d147c0ddfa31c2293c (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.lua | 69 |
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 |