实例
页面有如下标签
<?php echo '<img src=x onerror='.$_GET['input'].'>'; ?>
这时输入如下,实现弹窗
input=%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x31;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x63;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x35;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x37;%26%23x32;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x37;%26%23x34;(1)
解析
alert
的unicode编码->\u0061\u006c\u0065\u0072\u0074
再进行实体编码:
\u0061\u006c\u0065\u0072\u0074
最后进行url编码:
%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x31;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x63;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x36;%26%23x35;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x37;%26%23x32;%26%23x5C;%26%23x75;%26%23x30;%26%23x30;%26%23x37;%26%23x34;
当从url输入这一长串时后端服务器先urldecode变成实体编码放在了
<img src=x onerror='.$_GET['input'].'>
变成
<img src=x onerror='\u0061\u006c\u0065\u0072\u0074(1)'>
输出到浏览器上,浏览器的渲染引擎将实体解码成
<img src=x onerror='\u0061\u006c\u0065\u0072\u0074(1)'>
最后onerror触发js解析器解码成
<img src=x onerror='alert(1)'>
原理探索
RFC3986文档规定,Url中只允许包含英文字母(
a-zA-Z
)、数字(0-9
)、-_.~
4个特殊字符以及所有保留字符,如果想在url中输入除了以上的字符就需要URL编码
RFC3986中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]
只有普通英文字符和数字,特殊字符$-_.+!*'()
还有保留字符,才能出现在未经编码的Url之中
但是数据中包含特殊字符或者保留字时仍然需要编码–>
http请求(GET/POST)时,url/参数编码的过程分析
url输入->urlencode(utf-8)->全部转变成二进制传输->服务器将二进制转换成url编码的形式->urldecode成原始输入
unicode用二进制存储了所有符号,而utf-8则是使用并按照特定方式修改unicode,从而应用到具体的编码方案中。
href是属性,需要通过伪协议javascript来执行js代码
onerror是事件,本身就可执行js代码
3.长文-浏览器的工作原理:新式网络浏览器幕后揭秘
引用:
编码与解码,浏览器都做了什么