防止xss攻击的有效方法
<p>最近,有个项目突然接到总部的安全漏洞报告,查看后知道是XSS攻击。</p><p><strong>问题描述:</strong></p>
<p>在页面上有个隐藏域:</p>
<div class="codeText">
<div class="codeHead"><span class="lantxt">XML/HTML Code</span><span style="CURSOR: pointer" class="copyCodeText" onclick="copyIdText('code_4075')">复制内容到剪贴板</span></div>
<div id="code_4075">
<ol class="dp-xml">
<li class="alt"><span><span class="tag"><</span><span class="tag-name">input</span><span> </span><span class="attribute">type</span><span> = </span><span class="attribute-value">"hidden"</span><span> </span><span class="attribute">id</span><span> = </span><span class="attribute-value">"action"</span><span> </span><span class="attribute">value</span><span> = </span><span class="attribute-value">"${action}"</span><span class="tag">/></span><span> </span></span> </li>
</ol>
</div>
</div>
<p>当前页面提交到Controller时,未对action属性做任何处理,直接又回传到页面上</p>
<p>如果此时action被用户恶意修改为:***"<script>alert(1);</script>"***</p>
<p>此时当页面刷新时将执行alert(1),虽然错误不严重,但是任何安全隐患都应受到重视。</p>
<p><strong>解决思路:</strong></p>
<p>该问题是由于对用户输入数据(隐藏域)未做任何处理,导致非法数据被执行,那么解决该问题的核心思路就是对用户数据做严格处理,对任何页面传递的数据都不应过分信任,处理方法如下:</p>
<p>1.在页面上对action参数做转义处理,${action?html}(前端技术采用freemarker),但是此种方法只能对单个属性有效,如果此时项目处于维护期且有大量此种问题,修复的难度较大且不便于统一维护</p>
<p>2.在服务端对用户数据做转义处理,此时需要创建一个filter,对request进行二次封装,核心代码如下:</p>
<div class="codeText">
<div class="codeHead"><span class="lantxt">Java Code</span><span style="CURSOR: pointer" class="copyCodeText" onclick="copyIdText('code_5677')">复制内容到剪贴板</span></div>
<div id="code_5677">
<ol class="dp-j">
<li class="alt"><span><span class="keyword">import</span><span> javax.servlet.http.HttpServletRequest; </span></span></li>
<li><span></span><span class="keyword">import</span><span> javax.servlet.http.HttpServletRequestWrapper; </span></li>
<li class="alt"><span> </span></li>
<li><span></span><span class="keyword">import</span><span> org.apache.commons.lang3.StringEscapeUtils; </span></li>
<li class="alt"><span> </span></li>
<li><span></span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> XssRequestWrapper </span><span class="keyword">extends</span><span> HttpServletRequestWrapper { </span></li>
<li class="alt"><span> </span></li>
<li><span> </span><span class="keyword">public</span><span> XssRequestWrapper(HttpServletRequest request) { </span></li>
<li class="alt"><span> </span><span class="keyword">super</span><span>(request); </span></li>
<li><span> } </span></li>
<li class="alt"><span> </span></li>
<li><span> </span><span class="keyword">public</span><span> String getParameter(String name) { </span></li>
<li class="alt"><span> String value = </span><span class="keyword">super</span><span>.getParameter(name); </span></li>
<li><span> </span><span class="keyword">if</span><span> (value == </span><span class="keyword">null</span><span>) { </span></li>
<li class="alt"><span> </span><span class="keyword">return</span><span> </span><span class="keyword">null</span><span>; </span></li>
<li><span> } </span></li>
<li class="alt"><span> </span><span class="keyword">return</span><span> StringEscapeUtils.escapeHtml4(value); </span></li>
<li><span> } </span></li>
<li class="alt"><span> </span></li>
<li><span> </span><span class="keyword">public</span><span> String[] getParameterValues(String name) { </span></li>
<li class="alt"><span> String[] values = </span><span class="keyword">super</span><span>.getParameterValues(name); </span></li>
<li><span> </span><span class="keyword">if</span><span> (values == </span><span class="keyword">null</span><span>) { </span></li>
<li class="alt"><span> </span><span class="keyword">return</span><span> </span><span class="keyword">null</span><span>; </span></li>
<li><span> } </span></li>
<li class="alt"><span> String[] newValues = </span><span class="keyword">new</span><span> String; </span></li>
<li><span> </span><span class="keyword">for</span><span> (</span><span class="keyword">int</span><span> i = </span><span class="number">0</span><span>; i < values.length; i++) { </span></li>
<li class="alt"><span> newValues = StringEscapeUtils.escapeHtml4(values); </span></li>
<li><span> } </span></li>
<li class="alt"><span> </span><span class="keyword">return</span><span> newValues; </span></li>
<li><span> } </span></li>
<li class="alt"><span>} </span></li>
</ol>
</div>
</div>
<p>XssRequestWrapper是对request进行的二次封装,最核心的作用是对request中的参数进行转义处理(需要用到commons-lang3.jar)</p>
<p>定义filter,核心的代码如下:</p>
<div class="codeText">
<div class="codeHead"><span class="lantxt">Java Code</span><span style="CURSOR: pointer" class="copyCodeText" onclick="copyIdText('code_8021')">复制内容到剪贴板</span></div>
<div id="code_8021">
<ol class="dp-j">
<li class="alt"><span><span class="annotation">@Override</span><span> </span></span></li>
<li><span></span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> doFilter(ServletRequest request, </span></li>
<li class="alt"><span> ServletResponse response, </span></li>
<li><span> FilterChain chain) </span><span class="keyword">throws</span><span> IOException, ServletException { </span></li>
<li class="alt"><span> HttpServletRequest req = (HttpServletRequest) request; </span></li>
<li><span> chain.doFilter(</span><span class="keyword">new</span><span> <span style=</span><span class="string">"color: #000000;"</span><span>>XssRequestWrapper</span>(req), response); </span></li>
<li class="alt"><span>} </span></li>
</ol>
</div>
</div>
<p>在web.xml中配置指定请求进行过滤,可以有效防止xss攻击,希望本文所述对大家熟练掌握防止xss攻击的方法有所帮助。</p>
頁:
[1]