Nginx-Lua过滤POST请求
注:此文章会持续更新
2012 来的几天关于Hash攻击的文章不断,基本语言级别的都收到影响。
看了下 PHP 相关 patch,基本就是对 POST 的 key 数量做一个限制,其他提供的 patch 差不多也是如此。
刚好可以尝试一下 nginx-lua 模块,这里简单贴一些代码,编译步骤就略去。
本文只是根据 POST 参数个数进行简单校验的测试。
这里大概有几个步骤:
加载 conf/post-limit.lua,文件内容在下一段
access_by_lua_file 'conf/post-limit.lua';
conf/post-limit.lua 文件内容:
ngx.req.read_body()
local method = ngx.var.request_method
local max_size = 2 -- 参数最多个数,这里测试用,2个
if method == 'POST' then -- 只过滤 POST 请求
local data = ngx.req.get_body_data()
if data then
local count = 0
local i = 0
while true do
if count > max_size then -- 大于2次,重定向错误页面
ngx.redirect('/post-max-count')
end
i = string.find(data, '&', i+1) -- 查找 & 字符
if i == nil then break end
count = count + 1
end
else
ngx.redirect('/post-error')
end
end
原先 ngx.req.get_post_args 函数来判断,发现也收到 hash 的影响,最后采取原始的循环字符串版本。
完整 nginx 配置片段:
location /test {
access_by_lua_file 'conf/post-limit.lua';
root html;
}
reload nginx 即可。可以这样来访问测试:
$ curl --data "a=1&a=11&b=2" http://localhost/test/1.html
返回 405,可以正常 GET 页面内容。
$ curl --data "a=1&a=11&b=2&c=1" http://localhost/test/1.html
返回 302,重定向到 /post-max-error 错误。
想起之前用 ModPerl 重写了 Apache 的 TransHandler/AccessHandler,跟这个比较类似,加一些过滤器。
感谢 @agentzh 建议,需要注意一下,在 Nginx 配置中 client_max_body_size 和 client_body_buffer_size 需要设为相同大小。