胤禛与弘历 發表於 2016-1-19 15:11:42

防止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">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">&quot;hidden&quot;</span><span>&nbsp;</span><span class="attribute">id</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">&quot;action&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">&quot;${action}&quot;</span><span class="tag">/&gt;</span><span> &nbsp;&nbsp;</span></span> </li>
</ol>
</div>
</div>
<p>当前页面提交到Controller时,未对action属性做任何处理,直接又回传到页面上</p>
<p>如果此时action被用户恶意修改为:***&quot;&lt;script&gt;alert(1);&lt;/script&gt;&quot;***</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>&nbsp;javax.servlet.http.HttpServletRequest; &nbsp;&nbsp;</span></span></li>
    <li><span></span><span class="keyword">import</span><span>&nbsp;javax.servlet.http.HttpServletRequestWrapper; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span></span><span class="keyword">import</span><span>&nbsp;org.apache.commons.lang3.StringEscapeUtils; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;XssRequestWrapper&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HttpServletRequestWrapper&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;XssRequestWrapper(HttpServletRequest&nbsp;request)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">super</span><span>(request); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getParameter(String&nbsp;name)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;</span><span class="keyword">super</span><span>.getParameter(name); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(value&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;StringEscapeUtils.escapeHtml4(value); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String[]&nbsp;getParameterValues(String&nbsp;name)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;values&nbsp;=&nbsp;</span><span class="keyword">super</span><span>.getParameterValues(name); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(values&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;newValues&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;String; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;values.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newValues&nbsp;=&nbsp;StringEscapeUtils.escapeHtml4(values); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;newValues; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</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>&nbsp;&nbsp;</span></span></li>
    <li><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doFilter(ServletRequest&nbsp;request, &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServletResponse&nbsp;response, &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterChain&nbsp;chain)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;IOException,&nbsp;ServletException&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest&nbsp;req&nbsp;=&nbsp;(HttpServletRequest)&nbsp;request; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(</span><span class="keyword">new</span><span>&nbsp;&lt;span&nbsp;style=</span><span class="string">&quot;color:&nbsp;#000000;&quot;</span><span>&gt;XssRequestWrapper&lt;/span&gt;(req),&nbsp;response); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
</div>
<p>在web.xml中配置指定请求进行过滤,可以有效防止xss攻击,希望本文所述对大家熟练掌握防止xss攻击的方法有所帮助。</p>
頁: [1]
查看完整版本: 防止xss攻击的有效方法