├── wafconf ├── blackip ├── whiteip ├── whiteurl ├── useragent ├── blackurl ├── cookie ├── post └── args ├── .gitignore ├── access.lua ├── README.md ├── lib.lua ├── config.lua ├── init.lua └── LICENSE /wafconf/blackip: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wafconf/whiteip: -------------------------------------------------------------------------------- 1 | 127.0.0.1 2 | -------------------------------------------------------------------------------- /wafconf/whiteurl: -------------------------------------------------------------------------------- 1 | \.(js|css) 2 | \.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|map) 3 | captcha-waf\.html 4 | 403\.html 5 | -------------------------------------------------------------------------------- /wafconf/useragent: -------------------------------------------------------------------------------- 1 | (HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench) 2 | -------------------------------------------------------------------------------- /wafconf/blackurl: -------------------------------------------------------------------------------- 1 | \.(htaccess|bash_history) 2 | \.(bak|inc|old|mdb|sql|backup|java|class|tgz|gz|tar|zip)$ 3 | (jmx-console|admin-console|jmxinvokerservlet) 4 | java\.lang 5 | \.svn\/ 6 | /(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\w+).(php|jsp) 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | -------------------------------------------------------------------------------- /access.lua: -------------------------------------------------------------------------------- 1 | require "init" 2 | 3 | -- captcha url 4 | if ngx.re.match(ngx.var.request_uri,"^/captcha-waf.html","jo") then 5 | ngx.header.content_type = "text/html" 6 | ngx.say(config_waf_captcha_html) 7 | ngx.exit(200) 8 | end 9 | 10 | local function waf_main() 11 | if black_ip_check() then 12 | elseif white_ip_check() then 13 | elseif white_url_check() then 14 | elseif user_agent_attack_check() then 15 | elseif cc_attack_check() then 16 | elseif cookie_attack_check() then 17 | elseif url_attack_check() then 18 | elseif url_args_attack_check() then 19 | -- elseif post_attack_check() then 20 | else 21 | return 22 | end 23 | end 24 | 25 | waf_main() 26 | -------------------------------------------------------------------------------- /wafconf/cookie: -------------------------------------------------------------------------------- 1 | \.\./ 2 | \:\$ 3 | \$\{ 4 | select.+(from|limit) 5 | (?:(union(.*?)select)) 6 | having|rongjitest 7 | sleep\((\s*)(\d*)(\s*)\) 8 | benchmark\((.*)\,(.*)\) 9 | base64_decode\( 10 | (?:from\W+information_schema\W) 11 | (?:(?:current_)user|database|schema|connection_id)\s*\( 12 | (?:etc\/\W*passwd) 13 | into(\s+)+(?:dump|out)file\s* 14 | group\s+by.+\( 15 | xwork.MethodAccessor 16 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\( 17 | xwork\.MethodAccessor 18 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ 19 | java\.lang 20 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ 21 | -------------------------------------------------------------------------------- /wafconf/post: -------------------------------------------------------------------------------- 1 | \.\./ 2 | select.+(from|limit) 3 | (?:(union(.*?)select)) 4 | having|rongjitest 5 | sleep\((\s*)(\d*)(\s*)\) 6 | benchmark\((.*)\,(.*)\) 7 | base64_decode\( 8 | (?:from\W+information_schema\W) 9 | (?:(?:current_)user|database|schema|connection_id)\s*\( 10 | (?:etc\/\W*passwd) 11 | into(\s+)+(?:dump|out)file\s* 12 | group\s+by.+\( 13 | xwork.MethodAccessor 14 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\( 15 | xwork\.MethodAccessor 16 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ 17 | java\.lang 18 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ 19 | \<(iframe|script|body|img|layer|div|meta|style|base|object|input) 20 | (onmouseover|onerror|onload)\= 21 | -------------------------------------------------------------------------------- /wafconf/args: -------------------------------------------------------------------------------- 1 | \.\./ 2 | \:\$ 3 | \$\{ 4 | select.+(from|limit) 5 | (?:(union(.*?)select)) 6 | having|rongjitest 7 | sleep\((\s*)(\d*)(\s*)\) 8 | benchmark\((.*)\,(.*)\) 9 | base64_decode\( 10 | (?:from\W+information_schema\W) 11 | (?:(?:current_)user|database|schema|connection_id)\s*\( 12 | (?:etc\/\W*passwd) 13 | into(\s+)+(?:dump|out)file\s* 14 | group\s+by.+\( 15 | xwork.MethodAccessor 16 | (?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\( 17 | xwork\.MethodAccessor 18 | (gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/ 19 | java\.lang 20 | \$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[ 21 | \<(iframe|script|body|img|layer|div|meta|style|base|object|input) 22 | (onmouseover|onerror|onload)\= 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### ngx_lua_waf 2 | ngx_lua_waf是一个基于lua-nginx-module的web应用防火墙, 支持验证码验证 3 | 4 | ### OneinStack启用ngx_lua_waf 5 | ``` 6 | ~/oneinstack/addons.sh 7 | #install ngx_lua_waf 8 | ``` 9 | ### 手工安装 10 | ``` 11 | cd /root/oneinstack/src 12 | wget http://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz #推荐2.1版本 13 | wget https://github.com/openresty/lua-cjson/archive/2.1.0.6.tar.gz -o lua-cjson-2.1.0.6.tar.gz 14 | git clone https://github.com/simpl/ngx_devel_kit.git 15 | git clone https://github.com/openresty/lua-nginx-module.git 16 | tar xzf LuaJIT-2.1.0-beta3.tar.gz 17 | tar xzf lua-cjson-2.1.0.6.tar.gz 18 | cd LuaJIT-2.1.0-beta3 19 | make && make install 20 | cd ../lua-cjson-2.1.0.6 21 | sed -i 's@LUA_INCLUDE_DIR.*@LUA_INCLUDE_DIR \?= \$(PREFIX)/include/luajit-2.1@' Makefile 22 | make && make install 23 | cd .. 24 | export LUAJIT_LIB=/usr/local/lib 25 | export LUAJIT_INC=/usr/local/include/luajit-2.1 26 | sed -i "s@^nginx_modules_options=.*@nginx_modules_options='--with-ld-opt=-Wl,-rpath,/usr/local/lib --add-module=../lua-nginx-module --add-module=../ngx_devel_kit'@" options.conf 27 | ./install.sh --nginx_option 1 28 | 29 | ### 全局nginx新增waf 30 | cat > /usr/local/nginx/conf/waf.conf << EOF 31 | lua_shared_dict limit 20m; 32 | lua_package_path "/usr/local/nginx/conf/waf/?.lua;;"; 33 | init_by_lua_file "/usr/local/nginx/conf/waf/init.lua"; 34 | access_by_lua_file "/usr/local/nginx/conf/waf/access.lua"; 35 | EOF 36 | 37 | #vi /usr/local/nginx/conf/nginx.conf 38 | #include vhost/*.conf;下一行新增,如下 39 | include waf.conf; 40 | 41 | ### 单网站新增waf(推荐) 42 | cat > /usr/local/nginx/conf/waf.conf << EOF 43 | lua_shared_dict limit 20m; 44 | lua_package_path "/usr/local/nginx/conf/waf/?.lua;;"; 45 | init_by_lua_file "/usr/local/nginx/conf/waf/init.lua"; 46 | EOF 47 | 48 | #vi /usr/local/nginx/conf/vhost/www.example.com.conf 49 | #location ~ [^/]\.php(/|$) {下一行新增,如下 50 | access_by_lua_file "/usr/local/nginx/conf/waf/access.lua"; 51 | #注意:wordpress URL改成ngx.var.request_uri 52 | 66 local ATTACK_URL = ngx.var.host .. ngx.var.uri 53 | 67 -- local ATTACK_URL = ngx.var.host .. ngx.var.request_uri 54 | #改成: 55 | 66 -- local ATTACK_URL = ngx.var.host .. ngx.var.uri 56 | 67 local ATTACK_URL = ngx.var.host .. ngx.var.request_uri 57 | ``` 58 | 59 | ### Copyright 60 | copy以下项目:
61 | https://github.com/loveshell/ngx_lua_waf
62 | https://github.com/unixhot/waf 63 | -------------------------------------------------------------------------------- /lib.lua: -------------------------------------------------------------------------------- 1 | -- waf core lib 2 | require "config" 3 | 4 | -- Get the client IP 5 | function get_client_ip() 6 | local CLIENT_IP = ngx.req.get_headers(0)["X_real_ip"] 7 | if CLIENT_IP == nil then 8 | CLIENT_IP = ngx.req.get_headers(0)["X_Forwarded_For"] 9 | end 10 | if CLIENT_IP == nil then 11 | CLIENT_IP = ngx.var.remote_addr 12 | end 13 | if CLIENT_IP == nil then 14 | CLIENT_IP = "unknown" 15 | end 16 | return CLIENT_IP 17 | end 18 | 19 | -- Get the client user agent 20 | function get_user_agent() 21 | local USER_AGENT = ngx.var.http_user_agent 22 | if USER_AGENT == nil then 23 | USER_AGENT = "unknown" 24 | end 25 | return USER_AGENT 26 | end 27 | 28 | -- Get WAF rule 29 | function get_rule(rulefilename) 30 | local io = require "io" 31 | local RULE_PATH = config_rule_dir 32 | local RULE_FILE = io.open(RULE_PATH..'/'..rulefilename,"r") 33 | if RULE_FILE == nil then 34 | return 35 | end 36 | local RULE_TABLE = {} 37 | for line in RULE_FILE:lines() do 38 | table.insert(RULE_TABLE,line) 39 | end 40 | RULE_FILE:close() 41 | return(RULE_TABLE) 42 | end 43 | 44 | -- WAF log record for json,(use logstash codec => json) 45 | function log_record(method,url,data,ruletag) 46 | local cjson = require("cjson") 47 | local io = require "io" 48 | local LOG_PATH = config_log_dir 49 | local CLIENT_IP = get_client_ip() 50 | local USER_AGENT = get_user_agent() 51 | local SERVER_NAME = ngx.var.host 52 | local LOCAL_TIME = ngx.localtime() 53 | local log_json_obj = { 54 | client_ip = CLIENT_IP, 55 | local_time = LOCAL_TIME, 56 | server_name = SERVER_NAME, 57 | req_url = url, 58 | attack_method = method, 59 | req_data = data, 60 | rule_tag = ruletag, 61 | user_agent = USER_AGENT, 62 | } 63 | local LOG_LINE = cjson.encode(log_json_obj) 64 | local LOG_NAME = LOG_PATH..'/'..ngx.today().."_sec.log" 65 | local file = io.open(LOG_NAME,"a") 66 | if file == nil then 67 | return 68 | end 69 | file:write(LOG_LINE.."\n") 70 | file:flush() 71 | file:close() 72 | end 73 | 74 | -- test log 75 | function test_log_record(data) 76 | local cjson = require("cjson") 77 | local io = require "io" 78 | local LOG_PATH = config_log_dir 79 | local CLIENT_IP = get_client_ip() 80 | local LOCAL_TIME = ngx.localtime() 81 | local log_json_obj = { 82 | client_ip = CLIENT_IP, 83 | req_data = data, 84 | } 85 | local LOG_LINE = cjson.encode(log_json_obj) 86 | local LOG_NAME = LOG_PATH..'/'.."test.log" 87 | local file = io.open(LOG_NAME,"a") 88 | if file == nil then 89 | return 90 | end 91 | file:write(LOG_LINE.."\n") 92 | file:flush() 93 | file:close() 94 | end 95 | 96 | -- WAF return 97 | function waf_output() 98 | if config_waf_output == "redirect" then 99 | ngx.redirect(config_waf_redirect_url, 301) 100 | else 101 | ngx.header.content_type = "text/html" 102 | ngx.status = ngx.HTTP_FORBIDDEN 103 | ngx.say(config_output_html) 104 | ngx.exit(ngx.status) 105 | end 106 | end -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | --WAF config file,enable = "on",disable = "off" 2 | 3 | --waf status 4 | config_waf_enable = "on" 5 | --log dir 6 | config_log_dir = "/data/wwwlogs" 7 | --rule setting 8 | config_rule_dir = "/usr/local/nginx/conf/waf/wafconf" 9 | --enable/disable white url 10 | config_white_url_check = "on" 11 | --enable/disable white ip 12 | config_white_ip_check = "on" 13 | --enable/disable block ip 14 | config_black_ip_check = "on" 15 | --enable/disable url filtering 16 | config_url_check = "on" 17 | --enalbe/disable url args filtering 18 | config_url_args_check = "on" 19 | --enable/disable user agent filtering 20 | config_user_agent_check = "on" 21 | --enable/disable cookie deny filtering 22 | config_cookie_check = "on" 23 | --enable/disable cc filtering 24 | config_cc_check = "on" 25 | --cc rate the xxx of xxx seconds 26 | config_cc_rate = "60/60" 27 | --enable/disable post filtering 28 | config_post_check = "on" 29 | --config waf output redirect/html 30 | config_waf_output = "html" 31 | --if config_waf_output ,setting url 32 | config_waf_redirect_url = "/captcha" 33 | config_waf_captcha_html=[[ 34 | 35 | 36 | 37 | Please enter verification code - OneinStack WAF 38 | 48 | 49 | 50 |
51 |

52 |

Sorry...

53 |

54 |

Your query looks similar to an automated request from computer software. In order to protect 55 | our users, please forgive us for temporarily not processing your request.

56 |

To continue accessing the webpage, please enter the characters shown below:

57 |
58 | Captcha image 59 | 60 | 61 | 63 |
64 |
65 | 66 | 137 | 138 | 139 | ]] 140 | config_output_html=[[ 141 | 142 | 143 | 网站防火墙 144 | 151 | 152 | 153 |
154 |
155 |
网站防火墙
156 |
157 |

您的请求带有不合法参数,已被网站管理员设置拦截!

158 |

可能原因:您提交的内容包含危险的攻击请求

159 |

如何解决:

160 |
  • 1)检查提交内容;
  • 161 |
  • 2)如网站托管,请联系空间提供商;
  • 162 |
  • 3)普通网站访客,请联系网站管理员;
163 |
164 |
165 |
166 | 167 | ]] 168 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | -- WAF Action 2 | require "config" 3 | require "lib" 4 | 5 | -- args 6 | local rulematch = ngx.re.find 7 | local unescape = ngx.unescape_uri 8 | 9 | -- allow white ip 10 | function white_ip_check() 11 | if config_white_ip_check == "on" then 12 | local IP_WHITE_RULE = get_rule("whiteip") 13 | local WHITE_IP = get_client_ip() 14 | if IP_WHITE_RULE ~= nil then 15 | for _,rule in pairs(IP_WHITE_RULE) do 16 | if rule ~= "" and rulematch(WHITE_IP,rule,"jo") then 17 | -- log_record("White_IP",ngx.var.request_uri,"_","_") 18 | return true 19 | end 20 | end 21 | end 22 | end 23 | end 24 | 25 | -- deny black ip 26 | function black_ip_check() 27 | if config_black_ip_check == "on" then 28 | local IP_BLACK_RULE = get_rule("blackip") 29 | local BLACK_IP = get_client_ip() 30 | if IP_BLACK_RULE ~= nil then 31 | for _,rule in pairs(IP_BLACK_RULE) do 32 | if rule ~= "" and rulematch(BLACK_IP,rule,"jo") then 33 | -- log_record('BlackList_IP',ngx.var.request_uri,"_","_") 34 | if config_waf_enable == "on" then 35 | ngx.header.content_type = "text/html" 36 | ngx.say('Your IP blacklist, Please contact the administrator! ') 37 | return true 38 | end 39 | end 40 | end 41 | end 42 | end 43 | end 44 | 45 | -- allow white url 46 | function white_url_check() 47 | if config_white_url_check == "on" then 48 | local URL_WHITE_RULES = get_rule("whiteurl") 49 | local REQ_URI = string.lower(ngx.var.request_uri) 50 | if URL_WHITE_RULES ~= nil then 51 | for _,rule in pairs(URL_WHITE_RULES) do 52 | if rule ~= "" then 53 | local REQ_URI_LEN = string.len(REQ_URI) 54 | local rule_str = string.sub(rule,1,2) 55 | local from, to, err = rulematch(REQ_URI,string.lower(rule),"jo") 56 | if rule_str == "\\." then 57 | local wfrom, wto, werr = rulematch(unescape(REQ_URI),"%?","jo") 58 | if from and REQ_URI_LEN == to and wfrom == nil then 59 | return true 60 | end 61 | elseif from and rule_str == "\\/" and from == 1 then 62 | return true 63 | elseif from and from == 2 then 64 | return true 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | 72 | -- deny cc attack 73 | function cc_attack_check() 74 | if config_cc_check == "on" then 75 | local USER_AGENT = get_user_agent() 76 | local ARGS = ngx.var.args or "" 77 | 78 | local ATTACK_URL = ngx.var.host .. ngx.var.uri 79 | -- local ATTACK_URL = ngx.var.host .. ngx.var.request_uri 80 | -- local ATTACK_URL = ngx.var.host .. ngx.var.uri .. '?' .. ARGS 81 | 82 | local CC_TOKEN = get_client_ip() .. "." .. ngx.md5(string.lower(ATTACK_URL) .. USER_AGENT) 83 | local limit = ngx.shared.limit 84 | local CCcount=tonumber(string.match(config_cc_rate,'(.*)/')) 85 | local CCseconds=tonumber(string.match(config_cc_rate,'/(.*)')) 86 | local req,_ = limit:get(CC_TOKEN) 87 | if req then 88 | -- write("/data/wwwlogs/info.log",CC_TOKEN .."\t".. ATTACK_URL .. "\t".. "req: " .. req .."\n") 89 | if req > CCcount then 90 | log_record("CC_Attack",ngx.var.request_uri,"-","-") 91 | if config_waf_enable == "on" then 92 | local source = ngx.encode_base64(ngx.var.scheme.."://"..ngx.var.host..ngx.var.request_uri) 93 | local dest = '/captcha-waf.html' .. '?continue=' .. source 94 | local CCcountcode,_ = math.modf(CCcount/2); 95 | limit:set(CC_TOKEN,CCcountcode) 96 | ngx.redirect(dest,302) 97 | end 98 | else 99 | limit:incr(CC_TOKEN,1) 100 | end 101 | else 102 | limit:set(CC_TOKEN,1,CCseconds) 103 | end 104 | end 105 | return false 106 | end 107 | 108 | -- deny cookie 109 | function cookie_attack_check() 110 | if config_cookie_check == "on" then 111 | local COOKIE_RULES = get_rule("cookie") 112 | local USER_COOKIE = ngx.var.http_cookie 113 | if USER_COOKIE ~= nil then 114 | for _,rule in pairs(COOKIE_RULES) do 115 | if rule ~="" and rulematch(string.lower(USER_COOKIE),string.lower(rule),"jo") then 116 | log_record("Deny_Cookie",ngx.var.request_uri,"-",rule) 117 | if config_waf_enable == "on" then 118 | waf_output() 119 | return true 120 | end 121 | end 122 | end 123 | end 124 | end 125 | return false 126 | end 127 | 128 | -- deny url 129 | function url_attack_check() 130 | if config_url_check == "on" then 131 | local URL_RULES = get_rule("blackurl") 132 | local REQ_URI = ngx.var.request_uri 133 | for _,rule in pairs(URL_RULES) do 134 | if rule ~="" and rulematch(string.lower(REQ_URI),string.lower(rule),"jo") then 135 | log_record("Deny_URL",REQ_URI,"-",rule) 136 | if config_waf_enable == "on" then 137 | waf_output() 138 | return true 139 | end 140 | end 141 | end 142 | end 143 | return false 144 | end 145 | 146 | -- deny url args 147 | function url_args_attack_check() 148 | if config_url_args_check == "on" then 149 | local ARGS_RULES = get_rule('args') 150 | for _,rule in pairs(ARGS_RULES) do 151 | --local REQ_ARGS = ngx.req.get_uri_args() 152 | local REQ_ARGS, err = ngx.req.get_uri_args() 153 | if err == "truncated" then 154 | log_record("Deny_URL_Args_Many",ngx.var.request_uri,"-",rule) 155 | if config_waf_enable == "on" then 156 | waf_output() 157 | return true 158 | end 159 | end 160 | for key, val in pairs(REQ_ARGS) do 161 | if type(val) == "table" then 162 | ARGS_DATA = string.lower(table.concat(val, " ")) 163 | elseif type(val) == "boolean" then 164 | ARGS_DATA = nil 165 | else 166 | ARGS_DATA = string.lower(val) 167 | end 168 | if ARGS_DATA and type(ARGS_DATA) ~= "boolean" and rule ~="" and rulematch(unescape(ARGS_DATA),string.lower(rule),"jo") then 169 | log_record("Deny_URL_Args",ngx.var.request_uri,"-",rule) 170 | if config_waf_enable == "on" then 171 | waf_output() 172 | return true 173 | end 174 | end 175 | end 176 | end 177 | end 178 | return false 179 | end 180 | 181 | -- deny user agent 182 | function user_agent_attack_check() 183 | if config_user_agent_check == "on" then 184 | local USER_AGENT_RULES = get_rule("useragent") 185 | local USER_AGENT = ngx.var.http_user_agent 186 | if USER_AGENT ~= nil then 187 | for _,rule in pairs(USER_AGENT_RULES) do 188 | if rule ~="" and rulematch(string.lower(USER_AGENT),string.lower(rule),"jo") then 189 | log_record("Deny_User_Agent",ngx.var.request_uri,"-",rule) 190 | if config_waf_enable == "on" then 191 | waf_output() 192 | return true 193 | end 194 | end 195 | end 196 | end 197 | end 198 | return false 199 | end 200 | 201 | -- deny post 202 | function post_attack_check() 203 | if config_post_check == "on" and ngx.var.request_method == "POST" then 204 | local POST_RULES = get_rule("post") 205 | for _,rule in pairs(POST_RULES) do 206 | -- local REQ_POST = ngx.req.get_post_args() 207 | local REQ_POST, err = ngx.req.get_post_args() 208 | if err == "truncated" then 209 | log_record("Deny_POST_Many",ngx.var.request_uri,"-",rule) 210 | if config_waf_enable == "on" then 211 | waf_output() 212 | return true 213 | end 214 | end 215 | for key, val in pairs(REQ_POST) do 216 | if type(val) == "table" then 217 | POST_DATA = string.lower(table.concat(val, " ")) 218 | elseif type(val) == "boolean" then 219 | POST_DATA = nil 220 | else 221 | POST_DATA = string.lower(val) 222 | end 223 | if POST_DATA and rule ~="" and rulematch(unescape(POST_DATA),string.lower(rule),"jo") then 224 | log_record("Deny_POST",ngx.var.request_uri,"-",rule) 225 | if config_waf_enable == "on" then 226 | waf_output() 227 | return true 228 | end 229 | end 230 | end 231 | end 232 | return true 233 | end 234 | return false 235 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------