From fc7baf2f3800f1e2c5efc8c558b9ad11c1cbe312 Mon Sep 17 00:00:00 2001 From: potatso Date: Thu, 29 Jun 2023 17:34:00 +0800 Subject: [PATCH] api --- lib/resty/coraza.lua | 46 +++++++++++++++++++++++-------- t/integration_block_req_header.t | 2 ++ t/integration_block_resp_header.t | 2 ++ t/integration_passed.t | 2 ++ t/integration_with_coreruleset.t | 2 ++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/resty/coraza.lua b/lib/resty/coraza.lua index ffcfb4b..16a033d 100644 --- a/lib/resty/coraza.lua +++ b/lib/resty/coraza.lua @@ -50,7 +50,7 @@ function _M.do_access_filter() request.build_and_process_body(transaction) ngx_ctx.action, ngx_ctx.status_code = coraza.intervention(transaction) - _M.do_handle() + end function _M.do_free() @@ -67,15 +67,10 @@ function _M.do_handle() -- If request has disrupted by coraza, the transaction is freed and set to nil. -- Response which was disrupted doesn't make sense. if ngx_ctx.action ~= nil and ngx_ctx.transaction ~= nil then - nlog(warn_fmt([[Transaction %s request: "%s" is interrupted by policy. Action is %s]], - ngx_ctx.request_id, ngx_var.request, ngx_ctx.action)) + nlog(warn_fmt([[Transaction %s request: "%s" is interrupted by policy. Action is %s]], ngx_ctx.request_id, ngx_var.request, ngx_ctx.action)) if ngx_ctx.action == "drop" then - ngx.status = ngx_ctx.status_code - local ok, msg = pcall(ngx.say, fmt(consts.BLOCK_CONTENT_FORMAT, ngx_ctx.status_code)) - if ok == false then - nlog(err_fmt(msg)) - end - return ngx.exit(ngx.status) + ngx_ctx.is_disrupted = true + return ngx_ctx.status_code, fmt(consts.BLOCK_CONTENT_FORMAT, ngx_ctx.status_code) -- TODO: disrupted by more action --elseif ngx_ctx.action == "deny" then -- ngx.status = ngx_ctx.status_code @@ -87,11 +82,39 @@ function _M.do_handle() end end +function _M.do_interrupt() + -- transaction is interrupted by policy, be free firstly. + -- If request has disrupted by coraza, the transaction is freed and set to nil. + -- Response which was disrupted doesn't make sense. + if ngx_ctx.is_disrupted == true and ngx.get_phase() == "header_filter" then + nlog(debug_fmt("Transaction %s has been disrupted at request phrase. ignore", + ngx_ctx.request_id)) + return + end + local status_code, block_msg = _M.do_handle() + if status_code ~= nil then + ngx.status = ngx_ctx.status_code + local ok, msg = pcall(ngx.say, block_msg) + if ok == false then + nlog(err_fmt(msg)) + end + return ngx.exit(ngx.status) + -- TODO: disrupted by more action + -- elseif ngx_ctx.action == "deny" then + -- ngx.status = ngx_ctx.status_code + ---- NYI: cannot call this C function (yet) + ---- ngx.header.content_type = consts.BLOCK_CONTENT_TYPE + -- ngx.say(fmt(consts.BLOCK_CONTENT_FORMAT, ngx_ctx.status_code)) + -- eturn ngx.exit(ngx.status) + end +end + function _M.do_header_filter() - if ngx_ctx.action ~= nil then + if ngx_ctx.is_disrupted == true then -- If request was interrupted by coraza at access_by_lua phrase, the ngx_ctx.transaction will be set nil. -- We can bypass the check. - nlog(debug_fmt("Transaction %s has been disrupted at request phrase. ignore", ngx_ctx.request_id)) + nlog(debug_fmt("Transaction %s has been disrupted at request phrase. ignore", + ngx_ctx.request_id)) return end local h = ngx.resp.get_headers(0, true) @@ -112,7 +135,6 @@ function _M.do_header_filter() --coraza.process_response_body(ngx_ctx.transaction) ngx_ctx.action, ngx_ctx.status_code = coraza.intervention(ngx_ctx.transaction) - _M.do_handle() end return _M diff --git a/t/integration_block_req_header.t b/t/integration_block_req_header.t index 74a0b5d..af56a7f 100644 --- a/t/integration_block_req_header.t +++ b/t/integration_block_req_header.t @@ -17,6 +17,7 @@ our $LocationConfig = <<'_EOC_'; access_by_lua_block { local coraza = require "resty.coraza" coraza.do_access_filter() + coraza.do_interrupt() } content_by_lua_block { @@ -26,6 +27,7 @@ our $LocationConfig = <<'_EOC_'; header_filter_by_lua_block{ local coraza = require "resty.coraza" coraza.do_header_filter() + coraza.do_interrupt() } log_by_lua_block{ diff --git a/t/integration_block_resp_header.t b/t/integration_block_resp_header.t index 3b8069e..63e2a27 100644 --- a/t/integration_block_resp_header.t +++ b/t/integration_block_resp_header.t @@ -17,6 +17,7 @@ our $LocationConfig = <<'_EOC_'; access_by_lua_block { local coraza = require "resty.coraza" coraza.do_access_filter() + coraza.do_interrupt() } content_by_lua_block { @@ -26,6 +27,7 @@ our $LocationConfig = <<'_EOC_'; header_filter_by_lua_block{ local coraza = require "resty.coraza" coraza.do_header_filter() + coraza.do_interrupt() } log_by_lua_block{ diff --git a/t/integration_passed.t b/t/integration_passed.t index 4229206..c7978c6 100644 --- a/t/integration_passed.t +++ b/t/integration_passed.t @@ -16,6 +16,7 @@ our $LocationConfig = <<'_EOC_'; access_by_lua_block { local coraza = require "resty.coraza" coraza.do_access_filter() + coraza.do_interrupt() } content_by_lua_block { @@ -25,6 +26,7 @@ our $LocationConfig = <<'_EOC_'; header_filter_by_lua_block{ local coraza = require "resty.coraza" coraza.do_header_filter() + coraza.do_interrupt() } log_by_lua_block{ diff --git a/t/integration_with_coreruleset.t b/t/integration_with_coreruleset.t index 83d33f3..e0eeffc 100644 --- a/t/integration_with_coreruleset.t +++ b/t/integration_with_coreruleset.t @@ -20,6 +20,7 @@ our $LocationConfig = <<'_EOC_'; access_by_lua_block { local coraza = require "resty.coraza" coraza.do_access_filter() + coraza.do_interrupt() } content_by_lua_block { @@ -29,6 +30,7 @@ our $LocationConfig = <<'_EOC_'; header_filter_by_lua_block{ local coraza = require "resty.coraza" coraza.do_header_filter() + coraza.do_interrupt() } log_by_lua_block{