Skip to content

Commit

Permalink
chore: updated the code
Browse files Browse the repository at this point in the history
  • Loading branch information
potapo committed Jul 18, 2023
1 parent 83b2dbe commit 83f80c1
Show file tree
Hide file tree
Showing 9 changed files with 527 additions and 101 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ location /t {
coraza.do_header_filter()
coraza.do_interrupt()
}

body_filter_by_lua_block{
coraza.do_body_filter()
}

log_by_lua_block{
coraza.do_log()
coraza.do_free_transaction()
}
}
Expand All @@ -76,4 +79,7 @@ if you need more log for debug, please turn on the debug on nginx.
error_log logs/error.log debug;
```

the matched rules log will be logged at `ngx.ctx.coraza_msg` by `coraza.do_log()`
the matched rules log will be logged at `ngx.ctx.coraza_msg` by `coraza.do_log()`

# TODO:
1. block response when detected the event
37 changes: 15 additions & 22 deletions lib/resty/coraza.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local log = require "resty.coraza.log"
local request = require "resty.coraza.request"
local response = require "resty.coraza.response"
local coraza = require "resty.coraza.coraza"
local consts = require "resty.coraza.constants"

Expand All @@ -11,7 +12,7 @@ local err_fmt = log.err_fmt
local warn_fmt = log.warn_fmt

local _M = {
_VERSION = '1.0.2'
_VERSION = '1.0.0-rc2'
}

function _M.create_waf()
Expand Down Expand Up @@ -60,7 +61,7 @@ end
function _M.do_free_transaction()
local transaction = ngx.ctx.transaction
if transaction ~= nil then
nlog(debug_fmt("transaction %s is freed by coraza_free_transaction", ngx.ctx.request_id))
nlog(debug_fmt("is freed by coraza_free_transaction"))
ngx.ctx.transaction = nil
coraza.free_transaction(transaction)
end
Expand All @@ -71,7 +72,7 @@ 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([[request: "%s" is interrupted by policy. Action is %s]], ngx.var.request, ngx.ctx.action))
if ngx.ctx.action == "drop" or ngx.ctx.action == "deny" then
ngx.ctx.is_disrupted = true
return ngx.ctx.status_code, fmt(consts.BLOCK_CONTENT_FORMAT, ngx.ctx.status_code)
Expand All @@ -84,45 +85,37 @@ function _M.do_interrupt()
-- 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))
nlog(debug_fmt("has been disrupted at request phrase. ignore"))
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))
if ngx.get_phase() == "header_filter" then
response.clear_header_as_body_modified()
else
ngx.say(block_msg)
return ngx.exit(ngx.status)
end
return ngx.exit(ngx.status)
end
end

function _M.do_header_filter()
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("has been disrupted at request phrase. ignore"))
return
end
local h = ngx.resp.get_headers(0, true)
for k, v in pairs(h) do
coraza.add_response_header(ngx.ctx.transaction, k, v)
end
-- copy from https://github.com/SpiderLabs/ModSecurity-nginx/blob/d59e4ad121df702751940fd66bcc0b3ecb51a079/src/ngx_http_modsecurity_header_filter.c#L527
coraza.process_response_headers(ngx.ctx.transaction, ngx.status, "HTTP 1.1")

-- process http response headers(supports HPP)
response.build_and_process_header(ngx.ctx.transaction)

ngx.ctx.action, ngx.ctx.status_code = coraza.intervention(ngx.ctx.transaction)
end

function _M.do_body_filter()
-- TODO
end

function _M.do_log()
coraza.process_logging(ngx.ctx.transaction)
response.build_and_process_body(ngx.ctx.transaction)
end

return _M
112 changes: 42 additions & 70 deletions lib/resty/coraza/coraza.lua
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,10 @@ function _M.new_transaction(waf)
local ok, msg = pcall(coraza.coraza_new_transaction, waf, nil)
if ok then
ngx.ctx.request_id = ngx.var.request_id
nlog(debug_fmt("Success to creat new transaction id %s",
ngx.ctx.request_id))
nlog(debug_fmt("Success to creat new transaction"))
return msg
else
nlog(debug_fmt("Failed to creat new transaction id %s, msg: %s",
ngx.ctx.request_id, msg))
nlog(debug_fmt("Failed to creat new transaction, msg: %s", msg))
end
end

Expand All @@ -159,13 +157,13 @@ function _M.process_connection(transaction, sourceAddress, clientPort, serverHos
local ok, msg = pcall(coraza.coraza_process_connection, transaction, cast_to_c_char(sourceAddress),
tonumber(clientPort), cast_to_c_char(serverHost), tonumber(serverPort))
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_connection with " ..
nlog(debug_fmt("success to invoke coraza_process_connection with " ..
"sourceAddress:%s clientPort:%s serverHost:%s serverPort:%s",
ngx.ctx.request_id, sourceAddress, clientPort, serverHost, serverPort))
sourceAddress, clientPort, serverHost, serverPort))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_connection with " ..
nlog(err_fmt("failed to invoke coraza_process_connection with " ..
"sourceAddress:%s clientPort:%s serverHost:%s serverPort:%s msg: %s",
ngx.ctx.request_id, sourceAddress, clientPort, serverHost, serverPort, msg))
sourceAddress, clientPort, serverHost, serverPort, msg))
end
end

Expand All @@ -175,11 +173,11 @@ function _M.process_uri(transaction, uri, method, proto)
local ok, msg = pcall(coraza.coraza_process_uri, transaction, cast_to_c_char(uri),
cast_to_c_char(method), cast_to_c_char(proto))
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_uri with %s %s %s",
ngx.ctx.request_id, method, uri, proto))
nlog(debug_fmt("success to invoke coraza_process_uri with %s %s %s",
method, uri, proto))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_uri with %s %s %s. msg: %s",
ngx.ctx.request_id, ngx.ctx.request_id, method, uri, proto, msg))
nlog(err_fmt("failed to invoke coraza_process_uri with %s %s %s. msg: %s",
method, uri, proto, msg))
end
end

Expand All @@ -189,11 +187,11 @@ function _M.add_request_header(transaction, header_name, header_value)
local ok, msg = pcall(coraza.coraza_add_request_header, transaction,
cast_to_c_char(header_name), #header_name, cast_to_c_char(header_value), #header_value)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_add_request_header with %s:%s",
ngx.ctx.request_id, header_name, header_value))
nlog(debug_fmt("success to invoke coraza_add_request_header with %s:%s",
header_name, header_value))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_add_request_header with %s:%s. msg: %s",
ngx.ctx.request_id, header_name, header_value, msg))
nlog(err_fmt("failed to invoke coraza_add_request_header with %s:%s. msg: %s",
header_name, header_value, msg))
end
end

Expand All @@ -202,23 +200,21 @@ function _M.add_get_args(transaction, header_name, header_value)
local ok, msg = pcall(coraza.coraza_add_get_args, transaction,
cast_to_c_char(header_name), cast_to_c_char(header_value))
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_add_get_args with %s:%s",
ngx.ctx.request_id, header_name, header_value))
nlog(debug_fmt("success to invoke coraza_add_get_args with %s:%s",
header_name, header_value))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_add_get_args with %s:%s. msg: %s",
ngx.ctx.request_id, header_name, header_value, msg))
nlog(err_fmt("failed to invoke coraza_add_get_args with %s:%s. msg: %s",
header_name, header_value, msg))
end
end

function _M.process_request_headers(transaction)
-- extern int coraza_process_request_headers(coraza_transaction_t t);
local ok, msg = pcall(coraza.coraza_process_request_headers, transaction)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_request_headers",
ngx.ctx.request_id))
nlog(debug_fmt("success to invoke coraza_process_request_headers"))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_request_headers. msg: %s",
ngx.ctx.request_id, msg))
nlog(err_fmt("failed to invoke coraza_process_request_headers. msg: %s", msg))
end
end

Expand All @@ -233,11 +229,10 @@ function _M.intervention(transaction)
if status_code == 0 then
status_code = 403
end
nlog(debug_fmt("Transaction %s disrupted with status %s action %s",
ngx.ctx.request_id, status_code, action))
nlog(debug_fmt("disrupted with status %s action %s", status_code, action))
return action, status_code
else
nlog(debug_fmt("Failed to disrupt transaction %s, action is nil", ngx.ctx.request_id))
nlog(debug_fmt("Failed to disrupt, action is nil"))
return nil, nil
end

Expand All @@ -247,11 +242,9 @@ function _M.free_transaction(transaction)
-- extern int coraza_free_transaction(coraza_transaction_t t);
local ok, msg = coraza.coraza_free_transaction(transaction)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_free_transaction",
ngx.ctx.request_id))
nlog(debug_fmt("success to invoke coraza_free_transaction"))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_free_transaction. msg: %s",
ngx.ctx.request_id, msg))
nlog(err_fmt("failed to invoke coraza_free_transaction. msg: %s", msg))
end
end

Expand All @@ -260,11 +253,9 @@ function _M.append_request_body(transaction, body)
local ok, msg = pcall(coraza.coraza_append_request_body, transaction,
cast_to_c_char(body), #body)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_append_request_body with %s",
ngx.ctx.request_id, body))
nlog(debug_fmt("success to invoke coraza_append_request_body with %s", body))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_append_request_body with %s. msg: %s",
ngx.ctx.request_id, body, msg))
nlog(err_fmt("failed to invoke coraza_append_request_body with %s. msg: %s", body, msg))
end
end

Expand All @@ -274,23 +265,19 @@ function _M.request_body_from_file(transaction, file_path)
local ok, msg = pcall(coraza.coraza_request_body_from_file,
transaction, cast_to_c_char(file_path))
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_request_body_from_file with %s",
ngx.ctx.request_id, file_path))
nlog(debug_fmt("success to invoke coraza_request_body_from_file with %s", file_path))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_request_body_from_file with %s. msg: %s",
ngx.ctx.request_id, file_path, msg))
nlog(err_fmt("failed to invoke coraza_request_body_from_file with %s. msg: %s", file_path, msg))
end
end

function _M.process_request_body(transaction)
-- extern int coraza_process_request_body(coraza_transaction_t t);
local ok, msg = pcall(coraza.coraza_process_request_body, transaction)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_request_body",
ngx.ctx.request_id))
nlog(debug_fmt("success to invoke coraza_process_request_body"))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_request_body. msg: %s",
ngx.ctx.request_id, msg))
nlog(err_fmt("failed to invoke coraza_process_request_body. msg: %s", msg))
end
end

Expand All @@ -300,11 +287,11 @@ function _M.process_response_headers(transaction, status_code, proto)
local ok, msg = pcall(coraza.coraza_process_response_headers,transaction,
tonumber(status_code), cast_to_c_char(proto))
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_response_headers with %s %s",
ngx.ctx.request_id, status_code, proto))
nlog(debug_fmt("success to invoke coraza_process_response_headers with %s %s",
status_code, proto))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_response_headers with %s %s",
ngx.ctx.request_id, status_code, proto))
nlog(err_fmt("failed to invoke coraza_process_response_headers with %s %s, msg: %s",
status_code, proto, msg))
end
end

Expand All @@ -313,45 +300,30 @@ function _M.add_response_header(transaction, header_name, header_value)
-- int name_len, char* value, int value_len);
local ok, msg = pcall(coraza.coraza_add_response_header, transaction, cast_to_c_char(header_name), #header_name, cast_to_c_char(header_value), #header_value)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_add_response_header with %s:%s",
ngx.ctx.request_id, header_name, header_value))
nlog(debug_fmt("success to invoke coraza_add_response_header with %s:%s",
header_name, header_value))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_add_response_header with %s:%s. msg: %s",
ngx.ctx.request_id, header_name, header_value, msg))
nlog(err_fmt("failed to invoke coraza_add_response_header with %s:%s. msg: %s",
header_name, header_value, msg))
end
end

function _M.append_response_body(transaction, body)
local ok, msg = pcall(coraza.coraza_append_response_body, transaction,
cast_to_c_char(body), #body)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_append_response_body with %s",
ngx.ctx.request_id, body))
nlog(debug_fmt("success to invoke coraza_append_response_body with %s", body))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_append_response_body with %s, msg: %s",
ngx.ctx.request_id, body, msg))
nlog(err_fmt("failed to invoke coraza_append_response_body with %s, msg: %s", body, msg))
end
end

function _M.process_response_body(transaction)
local ok, msg = pcall(coraza.coraza_process_response_body,transaction)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_response_body",
ngx.ctx.request_id))
nlog(debug_fmt("success to invoke coraza_process_response_body"))
else
nlog(err_fmt("Transaction %s failed to invoke coraza_process_response_body. msg: %s",
ngx.ctx.request_id, msg))
end
end

function _M.process_logging(transaction)
local ok, msg = pcall(coraza.coraza_process_logging, transaction)
if ok then
nlog(debug_fmt("Transaction %s success to invoke coraza_process_logging",
ngx.ctx.request_id))
else
nlog(debug_fmt("Transaction %s failed to invoke coraza_process_logging. msg: %s",
ngx.ctx.request_id, msg))
nlog(err_fmt("failed to invoke coraza_process_response_body. msg: %s", msg))
end
end

Expand Down
10 changes: 7 additions & 3 deletions lib/resty/coraza/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ local WARN = ngx.WARN
local DEBUG = ngx.DEBUG

local function log(formatstring, ...)
return fmt("PID: "..ngx.worker.pid()..
"\tphrase: "..ngx.get_phase()..
"\tlua-resty-coraza: "..formatstring, ...)
local str = "PID: "..ngx.worker.pid()..
"\tphrase: "..ngx.get_phase()
if ngx.ctx.request_id ~= nil then
str = str.."\tTransaction: "..ngx.ctx.request_id
end
str = str.."\tlua-resty-coraza: "..formatstring
return fmt(str, ...)
end

function _M.err_fmt(formatstring, ...)
Expand Down
Loading

0 comments on commit 83f80c1

Please sign in to comment.