跨站脚本攻击(XSS)是网站制作中最常见的漏洞之一。原理非常简单,就是在用户输入一些代码,这些代码会导致浏览器执行一些脚本,从而达到攻击目的。
这些攻击性代码通常要使用"
<
>
来达到攻击目的。
比如:您搜索的内容是: ${question}
,其中${question}
是用户输入的内容。
如果用户输入<script>alert(1);</script>
,这时页面会就执行这段脚本代码。
或者您的搜索内容是 <input type="text" value="${question}">
,如果用户输入" onclick="alert(1);
。
最终页面为您的搜索内容是 <input type="text" value="" onclick="alert(1);">
,此时点击这个输入框会触发onclick
事件,从而达到攻击目的。
由此可知处理"
'
<
>
等特殊字符,是防止跨站脚本攻击(XSS)攻击的关键。可以通过HTML转义
来处理这些问题,HTML转义
会将"
'
<
>
转义为"
'
<
>
,从而防止这些攻击。
FreeMarker HTML转义:${username?html}
。
如上例,不应在页面直接输出用户输入的内容,而应先转义再输出。如:
您搜索的内容是: ${question?html}
您的搜索内容是 <input type="text" value="${question?html}">
跨站脚本攻击(XSS)无处不在,每个变量都需要小心的加上转义代码,容易遗漏。FreeMarker提供了一种对整个页面一次性加上转义的方法。
为了避免跨站脚本攻击(XSS),通常会对输出的内容做HTML转义,比如${foo?html}。但是所有变量都要做这个转义不仅麻烦,还容易遗忘。另外FreeMarker空值处理也很麻烦且容易遗忘,比如${foo!}
、${(user.username)!}
。
使用excape标签可以很好的解决这个问题。
[#escape x as (x)!?html]
...
${user.username}
...
[/#escape]
只要被这个标签包含的代码,都相当于加上了${(foo.bar)!?html}
,如${user.username}
相当于${(user.username)!?html}
。即包含了空值处理,也包含了HTML转义处理。
在escape标签内有对象不需要转义时,可以用noescape标签。
[#escape x as (x)!?html]
...
[#noescape]${text}[/#noescape]
...
[/#escape]
注意事项:必须对所有页面都加上转义代码,包括包含文件。比如页面A
加上了escape
转义代码并不代表这个页面可以高枕无忧,如果页面A
中使用include
标签包含了页面B
,而页面B
中并没有加escape
转义代码,则仍然有跨站脚本攻击(XSS)的风险。应该在页面B
也加入escape
转义代码。最为常见的是分页模板page.html
和提示页模板sys_operation_***.html
没有加上转义代码,分页模板可能被很多页面包含。
“我加了转义代码,可是检测软件任然报告有XSS漏洞”。这时应该查看详细的报告信息,看看哪个页面哪行代码出现XSS漏洞,然后再针对该代码进行HTML转义
处理。所有的XSS漏洞都必须依赖之前所说的"
'
<
>
等特殊字符,而HTML转义
必然可以处理这个问题。不存在幽灵式的XSS漏洞,不存在“不知道哪里有XSS漏洞,反正就是有”。