Skip to content

Instantly share code, notes, and snippets.

@zahna
Last active June 24, 2018 18:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zahna/570df52ed35629c86a902e1d8393e04f to your computer and use it in GitHub Desktop.
Save zahna/570df52ed35629c86a902e1d8393e04f to your computer and use it in GitHub Desktop.
-- https://github.com/openresty/lua-nginx-module#nginx-api-for-lua
-- https://www.nginx.com/resources/wiki/modules/lua/
-- http://www.staticshin.com/programming/definitely-an-open-resty-guide/
-- access_by_lua_file /path/to/waf.lua;
-- examine request
ngx.req.read_body()
local request_method = ngx.req.get_method()
local get_args = ngx.req.get_uri_args()
local post_args, err = ngx.req.get_post_args()
-- TODO: normalize request
-- TODO: store banned IP addresses for a period of time (maybe in a file?)
-- local banned_ip_addrs = {}
-- TODO: store/retrieve/update patterns from a file
local rules = {}
if ngx.var.waf_ruleset ~= nil then
ngx.log(ngx.STDERR, string.format("WAF ruleset: %s", ngx.var.waf_ruleset))
local f = io.open(ngx.var.waf_ruleset, "r")
rules = io.read(f, "*all")
io.close(f)
end
local uri_patterns = {[[/\.ht(access|passwd)]],
[[\\{4,}]],
"^/wp-content/.*\.php",
"^/wp-content/uploads/.*\.php",
"wp-config\.php.*"}
local query_patterns = {"information_schema", "suhosin"}
local post_patterns = {"information_schema", "jfdaksl.*"}
-- iterate through blocked URI patterns
uri = ngx.unescape_uri(ngx.var.request_uri)
ngx.log(ngx.STDERR, 'decoded uri: ', uri)
for i = 1, uri:len() do
if uri:byte(i) <= 32 then
ngx.log(ngx.STDERR, 'ascii ctrl chars found in ', uri)
-- return ngx.exit(ngx.HTTP_FORBIDDEN)
return true
end
if uri:byte(i) > 127 then
ngx.log(ngx.STDERR, 'extended chars found in ', uri)
-- return ngx.exit(ngx.HTTP_FORBIDDEN)
break
end
end
uri = string.lower(ngx.var.request_uri)
for i, pat in ipairs(uri_patterns) do
local m = ngx.re.match(string.lower(uri), pat)
if m then
ngx.log(ngx.STDERR, string.format('waf\'ed uri: %s', pat))
-- ngx.header["Content-Type"] = "text/html"
-- ngx.print("this request is forbidden and has been logged.")
return ngx.exit(ngx.HTTP_FORBIDDEN)
end
end
-- iterate through blocked GET query string patterns
if request_method == "GET" then
for k, v in pairs(get_args) do
if type(v) == "string" then
for i, pat in ipairs(query_patterns) do
local m = ngx.re.match(string.lower(v), pat)
if m then
ngx.log(ngx.STDERR, string.format('pattern: %s', pat))
-- ngx.print("this request is forbidden and has been logged.")
-- return ngx.exit(ngx.HTTP_FORBIDDEN)
return true
end
end
end
end
-- iterate through blocked POST data patterns
elseif request_method == "POST" then
for k, v in pairs(post_args) do
if type(v) == "string" then
for i, pat in ipairs(post_patterns) do
local m = ngx.re.match(string.lower(v), pat)
if m then
ngx.log(ngx.STDERR, string.format('pattern: %s', pat))
-- ngx.print("this request is forbidden and has been logged.")
-- return ngx.exit(ngx.HTTP_FORBIDDEN)
return true
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment