最近在bbs上看到一个这样的贴挺有意思,给大家分享下,顺便探讨下base64编码应用。
帖子内容大概如下:
在浏览器地址栏直接输入网址
https://xxxx.xx.com/user/queryUser.htm/']<<img src=x prompt(1)>>/
,会弹出确认框,通过js对网址进行正则判断,对<、>、prompt等关键字符进行转义后替换原先请求网址,发现网址已经转义,但是确认框还是会弹出,应该如何解决这个问题?
帖子问题分析:
访问上述地址,通常会报404错误,如apache会报/']<<img src=x prompt(1)>>/ was not found on this server.
,但是应该不会弹出prompt输入提示框。
除非应用服务器做了404重定向,并且在重定向页面输出页面错误地址,类似如下
<div class="panel-body">
<p>抱歉,您访问的页面不存在,请联系系统管理员!</p>
<p>页面地址为:<%=servlet_url%></p>
</div>
servlet_url为刚才输入的目标url地址,弹出效果如下图所示:
通过encodeURI或encodeURIComponent转码行不行?
通过js自带的encodeURI或encodeURIComponent对
']<<img src=x prompt(1)>>
字串进行编码行不行?
']<<img src%3Dx onerror%3Dprompt(1)>>
答案:行不通,encodeURI只是对=等字符进行编码处理,浏览器依然认识它是一个img元素,依然会弹出prompt提示框。
那么怎么办?进行base64编码吧,除了稍微会增加点字符串长度外,其它没啥问题,还相对安全,至少肉眼一下子看不明白base64串表示啥意思,具体处理如下:
1、js base64编码
js没有提供现成的base64编码函数,但是网上很多,随便找了个,https://www.cnblogs.com/pengchengzhong/p/6027663.html。
编码代码如下:
var str = "']<<img src=x prompt(1)>>";
var base = new Base64();
console.log(base.encode(str)); //J108PGltZyBzcmM9eCBvbmVycm9yPXByb21wdCgxKT4+
处理后新的url地址为:https://xxxx.xx.com/user/queryUser.htm/J108PGltZyBzcmM9eCBvbmVycm9yPXByb21wdCgxKT4+
okay不会再弹出prompt框了
2、后台解码处理,以java为例
import java.util.Base64;
...
public static void main(String[] args) throws Exception {
String output = new String(Base64.getDecoder().
decode("J108PGltZyBzcmM9eCBvbmVycm9yPXByb21wdCgxKT4+".getBytes()));
System.out.println(output); //']<<img src=x prompt(1)>>
}