Nginx_lua 100参数绕过原理详解
字数 860 2025-08-05 19:10:07
Nginx_lua 参数绕过原理详解
一、环境搭建
Nginx_lua 安装步骤
- 下载并解压Nginx源码:
wget 'https://openresty.org/download/nginx-1.19.3.tar.gz'
tar -xzvf nginx-1.19.3.tar.gz
cd nginx-1.19.3/
- 设置LuaJIT环境变量(根据版本选择):
# LuaJIT 2.0:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
# LuaJIT 2.1:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.1
- 配置并编译安装:
./configure --prefix=/opt/nginx \
--with-ld-opt="-Wl,-rpath,/path/to/luajit/lib" \
--add-module=/path/to/ngx_devel_kit \
--add-module=/path/to/lua-nginx-module
make -j2
make install
测试配置示例
在nginx.conf中添加以下配置:
location = /api2 {
content_by_lua_block {
tmp=''
for i,v in pairs(ngx.req.get_uri_args()) do
if type(i)=='string' then
tmp=tmp..i..' '
end
end
ngx.header.content_type = "application/json;"
ngx.status = 200
ngx.say(tmp)
ngx.exit(200)
}
}
二、漏洞原理分析
参数绕过机制
-
默认参数限制:Nginx_lua默认接受100个参数,超过100个参数时不会记录超出的部分
-
演示示例:
- 生成102个参数的Python脚本:
a='' for i in range(1,102): a=a+'id'+str(i)+'=11&' print(a)- 发送请求后,只有前100个参数会被处理,第101个及以后的参数会被忽略
源码分析
-
关键函数:
ngx.req.get_uri_args()存在参数数量限制 -
限制定义:在源码中定义为
NGX_HTTP_LUA_MAX_ARGS,默认值为100#ifndef NGX_HTTP_LUA_MAX_ARGS #define NGX_HTTP_LUA_MAX_ARGS 100 #endif -
参数解析流程:
- 读取等号(
=)前的部分作为key - 读取与号(
&)前的部分作为value - 保存到内存中并判断是否达到max限制
- 读取等号(
-
关键判断代码:
if (max > 0 && ++count == max) { lua_pushliteral(L, "truncated"); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua hit query args limit %d", max); return 2; }
三、安全影响与防御
潜在风险
- 攻击者可利用此特性绕过参数过滤或限制
- 可能导致WAF或其他安全防护措施失效
防御措施
-
修改默认参数限制:
# 在nginx配置中增加 lua_max_args 200; # 设置为适当的值 -
自定义参数处理逻辑,增加额外的参数数量检查
-
对于关键接口,实现严格的参数验证机制
四、技术细节补充
参数解析流程图
- 开始解析URI参数
- 查找
=分隔key和value - 查找
&分隔不同参数对 - 对每个参数进行URI解码
- 计数并检查是否达到max限制
- 如果达到限制则停止处理后续参数
- 返回已解析的参数表
相关函数说明
ngx_http_lua_parse_args(): 核心参数解析函数ngx_http_lua_unescape_uri(): 处理URI编码的解码ngx_http_lua_set_multi_value_table(): 将参数存入Lua表
五、总结
Nginx_lua模块默认的100个参数限制可能导致安全防护被绕过,了解这一机制有助于开发更安全的Nginx配置和Lua脚本。通过分析源码可以深入理解参数处理流程,为安全防护提供依据。