csrf support
This commit is contained in:
parent
efcad468ad
commit
a6420423a9
@ -10,11 +10,16 @@ __http_response = {}
|
||||
__module_paths = {}
|
||||
__module_bytecode = {}
|
||||
__ready_modules = {}
|
||||
__EXIT_SENTINEL = {} -- Unique object for exit identification
|
||||
|
||||
-- ======================================================================
|
||||
-- CORE SANDBOX FUNCTIONALITY
|
||||
-- ======================================================================
|
||||
|
||||
function exit()
|
||||
error(__EXIT_SENTINEL)
|
||||
end
|
||||
|
||||
-- Create environment inheriting from _G
|
||||
function __create_env(ctx)
|
||||
local env = setmetatable({}, {__index = _G})
|
||||
@ -35,10 +40,15 @@ function __execute_script(fn, ctx)
|
||||
__http_response = nil
|
||||
|
||||
local env = __create_env(ctx)
|
||||
env.exit = exit
|
||||
setfenv(fn, env)
|
||||
|
||||
local ok, result = pcall(fn)
|
||||
if not ok then
|
||||
if result == __EXIT_SENTINEL then
|
||||
return
|
||||
end
|
||||
|
||||
error(result, 0)
|
||||
end
|
||||
|
||||
@ -314,6 +324,58 @@ local session = {
|
||||
end
|
||||
}
|
||||
|
||||
-- ======================================================================
|
||||
-- CSRF MODULE
|
||||
-- ======================================================================
|
||||
|
||||
local csrf = {
|
||||
generate = function()
|
||||
local token = util.generate_token(32)
|
||||
session.set("_csrf_token", token)
|
||||
return token
|
||||
end,
|
||||
|
||||
field = function()
|
||||
local token = session.get("_csrf_token")
|
||||
if not token then
|
||||
token = csrf.generate()
|
||||
end
|
||||
return string.format('<input type="hidden" name="_csrf_token" value="%s" />', token)
|
||||
end,
|
||||
|
||||
validate = function()
|
||||
local env = getfenv(2)
|
||||
local token = false
|
||||
if env.ctx and env.ctx.session and env.ctx.session.data then
|
||||
token = env.ctx.session.data["_csrf_token"]
|
||||
end
|
||||
|
||||
if not token then
|
||||
http.set_status(403)
|
||||
__http_response.body = "CSRF validation failed"
|
||||
exit()
|
||||
end
|
||||
|
||||
local request_token = nil
|
||||
if env.ctx and env.ctx.form then
|
||||
request_token = env.ctx.form._csrf_token
|
||||
end
|
||||
|
||||
if not request_token and env.ctx and env.ctx._request_headers then
|
||||
request_token = env.ctx._request_headers["x-csrf-token"] or
|
||||
env.ctx._request_headers["csrf-token"]
|
||||
end
|
||||
|
||||
if not request_token or request_token ~= token then
|
||||
http.set_status(403)
|
||||
__http_response.body = "CSRF validation failed"
|
||||
exit()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
-- ======================================================================
|
||||
-- UTIL MODULE
|
||||
-- ======================================================================
|
||||
@ -404,5 +466,6 @@ local util = {
|
||||
|
||||
_G.http = http
|
||||
_G.session = session
|
||||
_G.csrf = csrf
|
||||
_G.cookie = cookie
|
||||
_G.util = util
|
||||
|
Loading…
x
Reference in New Issue
Block a user