Funny ngy_lua outcome
Nginx User
nginx at nginxuser.net
Sun Oct 23 14:20:07 UTC 2011
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()
-- <id>00</id>
local query_string = "//"
local query_match = ngx.re.match(my_arg, query_string, "io")
-- generic attacks
-- <impact>9</impact>
if query_match then
return "00"
end
-- <id>01</id>
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
-- <impact>4</impact>
if query_match then
return "01"
end
.....
ISSUES
1. 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.
2. 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.
3. 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
More information about the nginx
mailing list