luci-base: prevent UCI changes in CBI if form is not in submit state

Only process submitted data if the "cbi.submit" parameter is present as the
dispatcher will verify the integrity of the CSRF token in this case.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
This commit is contained in:
Jo-Philipp Wich 2015-10-07 21:44:46 +02:00
parent 281d2f6178
commit bd504f552d

View file

@ -367,23 +367,30 @@ end
-- Use optimized UCI writing -- Use optimized UCI writing
function Map.parse(self, readinput, ...) function Map.parse(self, readinput, ...)
self.readinput = (readinput ~= false)
self:_run_hooks("on_parse")
if self:formvalue("cbi.skip") then if self:formvalue("cbi.skip") then
self.state = FORM_SKIP self.state = FORM_SKIP
elseif not self.save then
self.state = FORM_INVALID
elseif not self:submitstate() then
self.state = FORM_NODATA
end
-- Back out early to prevent unauthorized changes on the subsequent parse
if self.state ~= nil then
return self:state_handler(self.state) return self:state_handler(self.state)
end end
self.readinput = (readinput ~= false)
self:_run_hooks("on_parse")
Node.parse(self, ...) Node.parse(self, ...)
if self.save then
self:_run_hooks("on_save", "on_before_save") self:_run_hooks("on_save", "on_before_save")
for i, config in ipairs(self.parsechain) do for i, config in ipairs(self.parsechain) do
self.uci:save(config) self.uci:save(config)
end end
self:_run_hooks("on_after_save") self:_run_hooks("on_after_save")
if self:submitstate() and ((not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply")) then if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then
self:_run_hooks("on_before_commit") self:_run_hooks("on_before_commit")
for i, config in ipairs(self.parsechain) do for i, config in ipairs(self.parsechain) do
self.uci:commit(config) self.uci:commit(config)
@ -404,7 +411,6 @@ function Map.parse(self, readinput, ...)
-- Reparse sections -- Reparse sections
Node.parse(self, true) Node.parse(self, true)
end end
for i, config in ipairs(self.parsechain) do for i, config in ipairs(self.parsechain) do
self.uci:unload(config) self.uci:unload(config)
@ -412,18 +418,13 @@ function Map.parse(self, readinput, ...)
if type(self.commit_handler) == "function" then if type(self.commit_handler) == "function" then
self:commit_handler(self:submitstate()) self:commit_handler(self:submitstate())
end end
end
if self:submitstate() then if self.proceed then
if not self.save then
self.state = FORM_INVALID
elseif self.proceed then
self.state = FORM_PROCEED self.state = FORM_PROCEED
elseif self.changed then
self.state = FORM_CHANGED
else else
self.state = self.changed and FORM_CHANGED or FORM_VALID self.state = FORM_VALID
end
else
self.state = FORM_NODATA
end end
return self:state_handler(self.state) return self:state_handler(self.state)