一 关于nginx uri过往整理
HTTP1.1(四)URI
HTTP1.1(五)URI编码
HTTP杂谈(三)URL特殊字符
以下'涉及':
1) location 与'$uri' --> '路由匹配' --> 通过'debug日志观察'
2) proxy_paas --> attach_url'是否'有,有'是否是变量',决定透传给'上游uri'的形式
3) $request、$request_uri、$uri --> '日志记录和响应体值形式'
4) if ($uri ~ '^([a-zA-Z0-9=%&?\-_]+$)') --> 'URI白名单或者URI截断'
5) rewrite .. break 、set、proxy_paas 改变 '$args'
HTTP框架提供的变量
proxy_pass指令
nginx(七十六)nginx与HTTP请求行的深入探论
nginx(七十八)日志的深入探究
$uri、try_files、index关系
nginx(三十二)rewrite模块
nginx(七十九)rewrite模块指令再探之(一)变量漫谈
nginx(八十)rewrite模块指令再探之(二)
使用 $uri 可导致 CRLF 注入
二 关于$uri和$request_uri难点探究
① 相关参考
url解码遇到%的问题
nginx uri转义原理深入讲解
源码探究URL转义
url特殊字符导致404
nginx uri中文
nginx lua uri 防盗链针对包含中文的问题
nginx url解码引发的waf漏洞
② 转义、编码、解码
escape --> '转义'
encode --> '编码'
decode --> '解码'
遗留:编码和转义是'一个意思'吗?
③ 日志细节探讨
1) 关注: log_format 'escape属性'探究
2) 对比'nginx日志'和'响应体'理解
说明: 默认是'escape=default'
细节: 浏览器自动对'中文'进行'编码'传输
原因: 由于'中文'不是浏览器认为的合法'ASCII字符',会按照'既定的规则'进行'编码'
'特殊的字符'转换成'ASCII码'规则:
1) 一个'中文'字符'utf-8'编码,对应'3'个'字节'
2) 每个'字节'对应'%hexhex'形式
3) 例如:'我'--> '%E6%88%91'
思考1: 为什么'nginx日志'和'响应体'不一样?
1) escape '转义' --> '仅仅是nginx 日志格式的可读性'
2) charset '编码' --> 设置'网页[响应体]'编码格式,而页面的解码与编码不一致则导致'乱码'
思考2: 为什么'$args'没有转义,nginx到底对于'url各部分'是如何处理转义的?
思考3: 为什么'十六进制的%'变为'\x'
④ %探究
1) 问题引入: '$uri'和'$request_uri'为什么'不一致'?
2) 测试2:在一个'uri中'包含了特殊字符'%'
现象: '400'报错
原理: '%号'后面如果'不是两位16进制数'会导致异常'NGX_HTTP_PARSE_INVALID_REQUEST'
目的: 防止'sql注入'等'攻击'风险
补充: 如果'特殊字符%'用在'查询参数中'则没问题
3) 测试3: 如何传递'%'特殊字符呢? --> 将'%'符号转义为'%25'
注意:特殊字符导致'400、404'的报错
⑤ nginx的uri转义机制
遗留:'阅读' src/core/ngx_string.h 和 src/core/ngx_string.c '源'文件
ngx_escape_uri函数
nginx模块和核心api
rfc3986#section-2.2
⑥ ngx_proxy模块对URI处理
补充: 'rewrite ... break;'会改变'proxy_paas'的uri形式
proxy_pass带attach_url导致解码后传输给上游 400报错
遗留:
1) 物料:弄两个nginx,一个作为'代理',一个作为'上游'服务器
备注:代理'proxy_paas'中'attach_url'三种形式 --> '本周闭环'
2) 测试: url带'特殊'字符,观察'代理和上游日志',以及'响应体'
⑦ $uri做if判断和做proxy_pass的attach_url
案例1: if ($uri ~ ^([a-zA-Z0-9_/]+)$) {...} 观察debug日志'匹配'情况
案例2: url'特殊'字符,多个'location 路由',观察匹配哪个'location'
案例3: proxy_paas的attach_url使用'$uri',观察'CLCF'漏洞注入的现象
--> '本周闭环'
nginx $uri导致的CRLF注入漏洞
⑧ nginx 过滤掉查询字符串
rewrite ^(.+)$ $1? break;
# rewrite ^ $uri? break
proxy_pass http://$proxy_name$uri;
⑨ ngx_lua 的 URI 转义机制
1) 自动把原始 url 带给后端应该是 'ngx_proxy 模块'的行为,和 'ngx_lua 没有'任何关系
2) 想强制 uri的归一化,应该使用'ngx.req.set_uri()' 这样的 Lua API 来'改写'当前请求的uri
题外话: 加载'相对资源'的时候,会传递一个'Referer'请求头