<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                XSS, 跨站腳本攻擊, 簡單來說, 就是非本站點的腳本被執行了。 關于XSS 的詳細介紹和防御參考: ![](https://img.kancloud.cn/43/58/4358b07e7d7def4a15bd89d4cb156ffe_600x460.png) [XSS(跨站腳本)攻擊與預防](https://blog.csdn.net/oscar999/article/details/127397397) 和 [跨站腳本攻擊(XSS)及防范措施](https://blog.csdn.net/oscar999/article/details/105369085)。 本篇介紹在Java 項目中如何快速修復XSS 漏洞。本篇使用的是黑名單的方式, 對于非法字符進行轉義。 黑名單的方式雖然不能完全的解決XSS的漏洞, 但是能有效的減輕攻擊, 對于使用類似Coverity等代碼靜態掃描攻擊掃描的漏洞, 修復之后就不會再報相關的警報了。 ## 個別代碼處理 如果整個項目中僅有幾處被掃描出來存在XSS 攻擊漏洞, 以基于Spring 項目的請求方法為例,下面的代碼是存在XSS 漏洞的。 ``` @RequestMapping("/unsafe") public String unsafe(@RequestParam(required = false) String input) { String s = "Hello"; s += input; return s; } ``` 上面的代碼中, 如果 input 包含了 `<script>`的腳本語句的話, 則這個響應返回給請求方的瀏覽器端, 相關的腳本就有可能被執行。 解決方法就是對返回的字符串進行黑名單過濾, 該怎么處理字符串呢? 內置tomcat 的jar 檔- tomcat-embed-core-9.0.14.jar 提供了一個類: org.apache.tomcat.util.security.Escape , 該類中的htmlElementContent() 方法實現了對特殊字符轉義,仿造這個方法寫一個類似的htmlElementContent() , 完整代碼如下: ``` public class SecurityUtil { /** * XSS 防御, 黑名單, 將非法字符進行替換 * @param content * @return */ public static String htmlElementContent(String content) { if (content == null) { return null; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < content.length(); i++) { char c = content.charAt(i); if (c == '<') { sb.append("&lt;"); } else if (c == '>') { sb.append("&gt;"); } else if (c == '\'') { sb.append("&#39;"); } else if (c == '&') { sb.append("&amp;"); } else if (c == '"') { sb.append("&quot;"); } else if (c == '/') { sb.append("&#47;"); } else { sb.append(c); } } return (sb.length() > content.length()) ? sb.toString() : content; } } ``` 對接口方法進行改寫,響應的字符串通過htmlElementContent() 進行處理后則基本是安全的, 如下代碼: ``` @RequestMapping("/safe") public String safe(@RequestParam(required = false) String input) { String s = "Hello"; s += input; return SecurityUtil.htmlElementContent(s); } ``` ## 過濾器統一處理 如果是Java Web項目中, 如果每一個請求處理方法都使用上面方式進行處理的話, 則需要處理的地方太多了, 比較好的方式是使用過濾器進行統一處理。 過濾器可以對請求和響應進行XSS 防御的處理, 比如定義一個XssFilter 如下: ``` /**?? *?@Title:?XssFilter.java *?@Package?com.osxm.websecurity.xss *?@Description:?TODO *?@author?XM *?@date?2023年1月8日?下午8:09:35 *?@Copyright:?2023 *?@version?V1.0?? */ package com.osxm.websecurity.xss; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; /** ?*?@ClassName?XssFilter ?*?@Description?TODO ?*?@author?XM ?*?@date?2023年1月8日 ?*? ?*/ public class XssFilter { FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(new XssWrapper((HttpServletRequest) request), response); } } ``` 在過濾器處理方法中, 使用XssWrapper對請求進行Xss 過濾, XssWrapper的內容如下: ``` /**?? *?@Title:?XssWrapper.java *?@Package?com.osxm.websecurity.xss *?@Description:?TODO *?@author?XM *?@date?2023年1月8日?下午8:10:49 *?@Copyright:?2023 *?@version?V1.0?? */ package com.osxm.websecurity.xss; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; /** ?*?@ClassName?XssWrapper ?*?@Description?TODO ?*?@author?XM ?*?@date?2023年1月8日 ?*? ?*/ public class XssWrapper extends HttpServletRequestWrapper { public static final String JSON_TYPE = "application/json"; public static final String CONTENT_TYPE = "Content-Type"; public static final String CHARSET = "UTF-8"; private String mBody; HttpServletRequest originalRequest = null; public XssWrapper(HttpServletRequest request) throws IOException { super(request); originalRequest = request; setRequestBody(request.getInputStream()); } /** * 獲取最原始的request。已經被getInputStream()了。 * * @return */ public HttpServletRequest getOrgRequest() { return originalRequest; } /** * 獲取最原始的request的靜態方法。已經被getInputStream()了。 * * @return */ public static HttpServletRequest getOriginalRequest(HttpServletRequest req) { if (req instanceof XssWrapper) { return ((XssWrapper) req).getOrgRequest(); } return req; } @Override public String getHeader(String name) { String value = super.getHeader(name); if (StringUtils.isBlank(value)) { return value; } return StringEscapeUtils.escapeHtml4(value); } @Override public String getQueryString() { return StringUtils.isBlank(super.getQueryString()) ? "" : StringEscapeUtils.escapeHtml4(super.getQueryString()); } @Override public String getParameter(String name) { String value = super.getParameter(name); if (StringUtils.isBlank(value)) { return value; } return StringEscapeUtils.escapeHtml4(value); } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (values == null) { return values; } for (int i = 0; i < values.length; i++) { values[i] = StringEscapeUtils.escapeHtml4(values[i]); } return values; } @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> map = new LinkedHashMap<String, String[]>(); Map<String, String[]> parameterMap = super.getParameterMap(); if (parameterMap == null) { return super.getParameterMap(); } for (String key : parameterMap.keySet()) { String[] values = parameterMap.get(key); if (values != null && values.length > 0) { for (int i = 0; i < values.length; i++) { values[i] = StringEscapeUtils.escapeHtml4(values[i]); } } map.put(key, values); } return map; } private void setRequestBody(InputStream stream) throws JsonMappingException, JsonProcessingException { String line = ""; StringBuilder body = new StringBuilder(); // 讀取POST提交的數據內容 BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName(CHARSET))); try { while ((line = reader.readLine()) != null) { body.append(line); } } catch (IOException e) { e.printStackTrace(); } mBody = body.toString(); if (StringUtils.isBlank(mBody)) {// 為空時,直接返回 return; } ObjectMapper objectMapper = new ObjectMapper(); Map<String, Object> map = objectMapper.readValue(mBody, Map.class); Map<String, Object> resultMap = new HashMap<>(map.size()); for (String key : map.keySet()) { Object val = map.get(key); if (map.get(key) instanceof String) { resultMap.put(key, StringEscapeUtils.escapeHtml4(val.toString())); } else { resultMap.put(key, val); } } mBody = objectMapper.writeValueAsString(resultMap); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { if (!JSON_TYPE.equalsIgnoreCase(super.getHeader(CONTENT_TYPE))) {// 非json類型,直接返回 return super.getInputStream(); } if (StringUtils.isBlank(mBody)) {// 為空時,直接返回 return super.getInputStream(); } final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes(CHARSET)); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener listener) { } }; } } ``` ## 示例代碼項目 * [https://github.com/osxm/websecurity_ency/tree/main/src/main/java/com/osxm/websecurity/xss](https://github.com/osxm/websecurity_ency/tree/main/src/main/java/com/osxm/websecurity/xss) ***** ***** https://www.cnblogs.com/wangsongbai/p/15065001.html
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看