防範xss攻擊-springboot程式碼實現
阿新 • • 發佈:2019-01-08
【現象】:form 提交可執行的HTML 標籤或JS 程式碼成功。比如:"/><script>alert('啦啦啦啦啦啦')</script><!- 或者
<img src='1.jpg' onload=alert(1)>
【後果】:盜取使用者cookie 資訊、網頁釣魚攻擊、修改網站程式碼、網站重定向。
【原因】: 提交的內容未做任何處理就入庫。
【解決方案】: 對所有入庫的資料轉碼HtmlUtils.htmlEscape,增加加Filter
【程式碼實現】
1.定義一個過濾器
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * @Description: 轉義所有form資料的過濾器 */ public class XSSFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; filterChain.doFilter(new XSSRequestWrapper(request) , servletResponse); } @Override public void destroy() { } }
2.寫一個包裝類
import org.springframework.web.util.HtmlUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * @Auther: Lee * @Date: 2018-08-14 * @Description: request的包裝類 */ public class XSSRequestWrapper extends HttpServletRequestWrapper { public XSSRequestWrapper(HttpServletRequest request) { super(request); } @Override public String[] getParameterValues(String name) { //獲取所有引數值的集合 String[] results = this.getParameterMap().get(name); if (results != null && results.length > 0) { int length = results.length; for (int i = 0; i < length; i++) { //過濾引數值 results[i] = HtmlUtils.htmlEscape(results[i]); } return results; } return null; } }
3.編寫一個URL過濾器,得到所有需要過濾的URL的集合
import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; /** * 從springContext中獲取所有ControllerMapping 並過濾出含有save的url,這些url的請求會經過TransferFilter */ @Component public class FilterUrlMapping { @Autowired ApplicationContext applicationContext; //@Bean public Set<String> allUrlMappings() { Set<String> result = new HashSet(); RequestMappingHandlerMapping rmhp = applicationContext.getBean(RequestMappingHandlerMapping.class); Map<RequestMappingInfo, HandlerMethod> map = rmhp.getHandlerMethods(); for (RequestMappingInfo info : map.keySet()) { //getMatchingPatterns優化 result.add(info.getPatternsCondition().toString().replace("[", "").replace("]", "")); } return result; } @Bean public FilterRegistrationBean filterRegistration() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new XSSFilter());//新增過濾器 Set<String> allSaveUrlPattern = allUrlMappings();//emsBasePrivilegeDao.findAllSaveUrlPattern(); if(CollectionUtils.isEmpty(allSaveUrlPattern)){ return filterRegistration; } String pattern = "/*.*save.*";// save Set<String> urlPatterns = new LinkedHashSet(); for (String saveUrlPattern : allSaveUrlPattern) { if (Pattern.matches(pattern, saveUrlPattern)) { urlPatterns.add(saveUrlPattern); } } filterRegistration.setUrlPatterns(urlPatterns); filterRegistration.setName("XSSFilter");// return filterRegistration; } }