Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 54 additions & 28 deletions attachments/kong/plugins/open-appsec-waf-kong-plugin/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ local kong = kong

local NanoHandler = {}

local function handle_verdict(ctx, verdict, response, session_data)
if verdict ~= nano.AttachmentVerdict.INSPECT then
ctx.cleanup_needed = true
if verdict == nano.AttachmentVerdict.DROP then
return nano.handle_custom_response(session_data, response)
end
return true
end
return false
end

local function validate_context(ctx)
return ctx and ctx.session_data and ctx.session_id
end

NanoHandler.PRIORITY = 3000
NanoHandler.VERSION = "1.0.0"

Expand All @@ -20,7 +35,7 @@ function NanoHandler.access(conf)

local session_data = nano.init_session(session_id)
if not session_data then
kong.ctx.plugin.cleanup_needed = false
ctx.cleanup_needed = false
return
end

Expand Down Expand Up @@ -49,31 +64,23 @@ function NanoHandler.access(conf)
local contains_body = has_content_length and 1 or 0

local verdict, response = nano.send_data(session_id, session_data, meta_data, req_headers, contains_body, nano.HttpChunkType.HTTP_REQUEST_FILTER)
if verdict ~= nano.AttachmentVerdict.INSPECT then
ctx.cleanup_needed = true
if verdict == nano.AttachmentVerdict.DROP then
return nano.handle_custom_response(session_data, response)
end
if handle_verdict(ctx, verdict, response, session_data) then
return
end

if contains_body == 1 then
local body = kong.request.get_raw_body()
if body and #body > 0 then
verdict, response = nano.send_body(session_id, session_data, body, nano.HttpChunkType.HTTP_REQUEST_BODY)
if verdict ~= nano.AttachmentVerdict.INSPECT then
ctx.cleanup_needed = true
if verdict == nano.AttachmentVerdict.DROP then
return nano.handle_custom_response(session_data, response)
end
if handle_verdict(ctx, verdict, response, session_data) then
return
end
else
local body_file = ngx.var.request_body_file
if body_file then
local file = io.open(body_file, "rb")
if file then
local chunk_size = 8192
local chunk_size = nano.CHUNK_SIZE
local chunk_count = 0
local start_time = ngx.now()
local timeout_sec = nano.get_request_processing_timeout_sec()
Expand Down Expand Up @@ -101,17 +108,16 @@ function NanoHandler.access(conf)
kong.log.debug("Sending request body chunk ", chunk_count, " of size ", #chunk, " bytes to C module")
verdict, response = nano.send_body(session_id, session_data, chunk, nano.HttpChunkType.HTTP_REQUEST_BODY)

if verdict ~= nano.AttachmentVerdict.INSPECT then
if handle_verdict(ctx, verdict, response, session_data) then
file:close()
ctx.cleanup_needed = true
if verdict == nano.AttachmentVerdict.DROP then
return nano.handle_custom_response(session_data, response)
end
return
end
end
file:close()
kong.log.debug("Sent ", chunk_count, " chunks from request body file")
else
kong.log.err("Failed to open request body file: ", err or "unknown error")
ctx.cleanup_needed = true
end
else
kong.log.err("Request body expected but no body data or file available")
Expand All @@ -128,18 +134,19 @@ function NanoHandler.access(conf)
return
end

if verdict ~= nano.AttachmentVerdict.INSPECT then
ctx.cleanup_needed = true
if verdict == nano.AttachmentVerdict.DROP then
return nano.handle_custom_response(session_data, response)
end
if handle_verdict(ctx, verdict, response, session_data) then
return
end
end
end

function NanoHandler.header_filter(conf)
local ctx = kong.ctx.plugin

if not validate_context(ctx) then
return
end

if nano.is_session_finalized(ctx.session_data) then
kong.log.debug("Session has already been inspected, no need for further inspection")
return
Expand Down Expand Up @@ -183,6 +190,11 @@ end

function NanoHandler.body_filter(conf)
local ctx = kong.ctx.plugin

if not validate_context(ctx) then
return
end

local chunk = ngx.arg[1]
local eof = ngx.arg[2]

Expand Down Expand Up @@ -241,8 +253,16 @@ function NanoHandler.body_filter(conf)

if eof then
if ctx.body_seen or ctx.expect_body == false then
ctx.cleanup_needed = true
local verdict, response = nano.end_inspection(session_id, session_data, nano.HttpChunkType.HTTP_RESPONSE_END)
local ok, verdict, response = pcall(function()
return nano.end_inspection(session_id, session_data, nano.HttpChunkType.HTTP_RESPONSE_END)
end)

if not ok then
kong.log.err("Error ending response inspection: ", verdict, " - failing open")
ctx.cleanup_needed = true
return
end

if verdict ~= nano.AttachmentVerdict.INSPECT then
kong.log.debug("Final verdict after end_inspection: ", verdict)
ctx.cleanup_needed = true
Expand All @@ -255,15 +275,21 @@ function NanoHandler.body_filter(conf)
end
end
end

ctx.cleanup_needed = true
end
end

function NanoHandler.log(conf)
local ctx = kong.ctx.plugin
if ctx.cleanup_needed then
nano.fini_session(ctx.session_data)
nano.cleanup_all()
if not ctx then
return
end

if ctx.session_data then
if ctx.cleanup_needed then
nano.fini_session(ctx.session_data)
nano.cleanup_all()
end
ctx.session_data = nil
ctx.session_id = nil
collectgarbage("collect")
Expand Down
Loading