哦,我其实想知道哪些 其它非 /admin/xxx 的路径 被 ^/admin/ 给匹配到了。
另外匹配 request_uri 而不是 uri 会有下面这样的问题:
¥ curl "localhost:11111/admin/../x" -v --path-as-is
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 11111 (#0)
> GET /admin/../x HTTP/1.1
> Host: localhost:11111
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: openresty+/1.13.6.1.25 (no pool)
< Date: Fri, 20 Apr 2018 16:29:13 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
<
ngx.var.request_uri: /admin/../x
ngx.var.uri: /x
一不小心过滤规则就会被绕过了……
在 2018年4月21日 上午12:19,Sindery Minami <minami...@gmail.com> 写道:
> 感谢回复。
>
> 非 /admin/xxx 的路径就很多了,包括并不限于我在后面那段测试代码中的例子,就是没有规则的随便写的。
>
> 使用 ngx.var.request_uri 是因为我其它代码中有重定向的部分,而我需要对原始请求做判断。
>
> 在 2018年4月21日星期六 UTC+8上午12:00:01,Zexuan Luo写道:
>>
>> > 但问题在后面,我访问其它非 /admin/xxx 的路径也会被连接中断,这就表明 ^/admin/ 并没有对 /admin/xxx
>> > 进行唯一匹配,也还对其它 /xxx/xxx/... 路径进行了匹配。
>>
>> 其他非 /admin/xxx 的路径是什么呢?
>>
>> 顺便一提,过滤 url 时最好用 normalized 之后 ngx.var.uri 而不是
>> ngx.var.request_uri。不然会有被绕过的风险。
>>
>> 在 2018年4月20日 下午11:43,Sindery Minami <minami...@gmail.com> 写道:
>> > ## 描述我的问题
>> > 系统: debian 8.0 x64
>> > 服务端: Openresty 1.13.6.1 默认安装
>> > 新手,问得比较简单,望见谅
>> >
>> > 问题描述:
>> > 我需要实现对 request_uri(请求路径) /admin/xxx 进行唯一匹配,所以我选择了 ngx.re.find 语法:
>> > language-lua
>> > if (ngx.re.find(ngx.var.request_uri, "^/admin/", "jo") ~= nil) then
>> > return ngx.exit(ngx.HTTP_CLOSE)
>> > end
>> > 使用这段代码后,我访问 /admin/xxx 路径(其中 xxx 为任意值或为空)会被连接中断而拒绝访问(ngx.HTTP_CLOSE ==
>> > return 444),这个匹配成功了。
>> >
>> > 但问题在后面,我访问其它非 /admin/xxx 的路径也会被连接中断,这就表明 ^/admin/ 并没有对 /admin/xxx
>> > 进行唯一匹配,也还对其它 /xxx/xxx/... 路径进行了匹配。
>> >
>> >
>> > ## 我的尝试
>> > 为了尝试是不是 "^/admin/" 这个正则的错误,我做了以下尝试:
>> >
>> > ### 修改正则
>> > 我也尝试过把正则写法换成 "^(/admin/)" 或 "^\/admin\/" 或
>> > "^(\/admin\/)",第一种写法的结果和上文所述一样(之后还单独做了正则验证,表明 ^/admin/ 和 ^(/admin/)
>> > 匹配结果一致,在下文会提到),后两种使用转义符号的写法都返回 500 错误(debug 表明语法错误,无法 load lua 脚本)
>> >
>> > ### 验证正则
>> > 上面提到我单独做了正则验证,为了进行验证,我将以下代码放进网站:
>> > language-lua
>> > if (ngx.var.request_uri == "/test1/") then
>> > if (ngx.re.find("/admin/test/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("1=" .. ngx.re.find("/admin/test/", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test2/") then
>> > if (ngx.re.find("/admintest/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("2=" .. ngx.re.find("/admintest/", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test3/") then
>> > if (ngx.re.find("/artic/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("3=" .. ngx.re.find("/artic/", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test4/") then
>> > if (ngx.re.find("/artic", "^/admin/", "jo") ~= nil) then
>> > ngx.say("4=" .. ngx.re.find("/artic", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test5/") then
>> > if (ngx.re.find("/offline/admin/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("5=" .. ngx.re.find("/offline/admin/", "^/admin/",
>> > "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test6/") then
>> > if (ngx.re.find("/offline/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("6=" .. ngx.re.find("/offline/", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test7/") then
>> > if (ngx.re.find("/admin/", "^/admin/", "jo") ~= nil) then
>> > ngx.say("7=" .. ngx.re.find("/admin/", "^/admin/", "jo"))
>> > end
>> > elseif (ngx.var.request_uri == "/test8/") then
>> > if (ngx.re.find("/adm/in", "^/admin/", "jo") ~= nil) then
>> > ngx.say("8=" .. ngx.re.find("/adm/in", "^/admin/", "jo"))
>> > end
>> > else
>> > if (ngx.var.request_uri == "/test9/") then
>> > if (ngx.re.find("/admin", "^/admin/", "jo") ~= nil) then
>> > ngx.say("9=" .. ngx.re.find("/admin", "^/admin/", "jo"))
>> > end
>> > end
>> > end
>> >
>> > 然后依次访问对应路径,只有第一个和第七个分别返回 "1=1" 和 "7=1",这却表明我的正则没写错,也将其中 ^/admin/ 换成
>> > ^(/admin/) 试过,结果一致。
>> >
>> >
>> > ### 确认不是我其它地方的错误
>> > 例如也有可能是我其它脚本有什么错误,所以我试着把 ngx.re.find 换成 Lua 的string.find 正则规范:
>> > language-lua
>> > if (string.find(ngx.var.request_uri, "^/admin/") ~= nil) then
>> > return ngx.exit(ngx.HTTP_CLOSE)
>> > end
>> > 然后却发现匹配没有问题了,由此可知确认不是我其它地方的错误。
>> >
>> > --
>> > --
>