SETUP
CONF FILE
server {
location @proxy {
access_by_lua_file ‘/etc/nginx/firewall.lua’;
proxy_cache proxy.capture360.net;
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/proxy.default;
}
location /error_docs {
internal;
alias /usr/share/nginx/html;
sub_filter '<!-- SubTag -->' '$host';
sub_filter_once off;
}
location @pretty_urls {
# – Several rewrite X Y break lines
rewrite_by_lua 'ngx.exec("@proxy");';
}
location / {
try_files $uri $uri/ @pretty_urls;
}
location ~ .+.php$ {
location ~ ../..php$ { return 400; }
rewrite_by_lua ‘ngx.exec(“@proxy”);’;
}
}
FIREWALL.LUA
– F. Check “GET” Args
if ngx.var.request_method == “GET” then
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
if type(val) == “table” then
my_arg = table.concat(val, " ")
else
my_arg = val
end
if my_arg and my_arg ~= “” and type(my_arg) ~= “boolean” then
rule_id = regex_rules.check()
if rule_id then
ngx.log(ngx.INFO, "Firewall Match: Rule " … rule_id … " on
POST: " … my_arg)
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
end
end
end
– G. Check “POST” Args
if ngx.var.request_method == “POST” then
ngx.req.read_body()
local args = ngx.req.get_post_args()
for key, val in pairs(args) do
if type(val) == “table” then
my_arg = table.concat(val, " ")
else
my_arg = val
end
if my_arg and my_arg ~= “” and type(my_arg) ~= “boolean” then
rule_id = regex_rules.check()
if rule_id then
ngx.log(ngx.INFO, "Firewall Match: Rule " … rule_id … " on
POST: " … my_arg)
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
end
end
ngx.req.discard_body()
end
REGEX_RULES.LUA
module(“regex_rules”, package.seeall)
function check()
– 00
local query_string = “//”
local query_match = ngx.re.match(my_arg, query_string, “io”)
– generic attacks
– 9
if query_match then
return “00”
end
– 01
local query_string =
“(?:"[^"][^-]?>)|(?:[^\\w\\s]\\s\/>)|(?:>")”
local query_match = ngx.re.match(my_arg, query_string, “io”)
– finds html breaking injections including whitespace attacks –
xss – csrf
– 4
if query_match then
return “01”
end
…
ISSUES
-
A googlebot visit while testing a post string designed to be
blocked “language=vbscript” is also blocked as the googlebot request
is also tested against the same string. -
Despite the “return id” line, the regex rules are run to the end.
I.E., if there is a match on Rule 02, the rest are still run anyway
and only after the last is evaluated is the 400 error returned. -
The log from “ngx.log” does not seem to be produced.
COMMENTARY
Abridged debug log with commentary here: http://pastebin.com/A0cXpHwg
(Lost the one with thegooglebot issue)
Issue 1 seems to be a variable scope issue with “my_arg” but when I
use"local" regex_rules.check() gets fed a blank.
Could the log thing be a level issue? I.E. “ngx.INFO” is too low??
Thanks