电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

springboot項目如何防止XSS攻擊

瀏覽:73日期:2023-03-02 08:50:54
目錄1. 什么是XSS攻擊?2. 如何防范?2.1 什么時候注入請求參數3. 具體處理細節1. 什么是XSS攻擊?

XSS攻擊全稱跨站腳本攻擊,是一種在web應用中的計算機安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。也就是作惡的用戶通過表單提交一些前端代碼,如果不做處理的話,這些前端代碼將會在展示的時候被瀏覽器執行。

2. 如何防范?

有兩種方式,一種是一些特殊字符轉義,另一種是去除一些危險html元素。本文通過JSOUP庫實現第二種方式。

現在問題是,在什么時候對XSS攻擊的字符串進行處理呢?這就涉及到spring mvc的Controller中的method params什么時候注入的問題。下面對方法參數注入的原理進行簡單說明。

2.1 什么時候注入請求參數

常見的控制器方法有下面幾種,分別是通過GET獲取請求參數,POST獲取json或者form表單的參數

/** * 通過url的path,獲取請求參數 */@ResponseBody@GetMapping('/xssByGetUsingPath/{content}')public String testGetUsingPath(@PathVariable(name = 'content') String content) { return content;}/** * 通過url的query params獲取請求數據. 方法使用簡單類型進行接收 */@ResponseBody@GetMapping('/xssByGetUsingSimple')public String testUsingSimple(@RequestParam(name = 'content') String content) { return content;}/** * 通過url的query params獲取請求數據. 方法使用model進行接收 */@ResponseBody@GetMapping('/xssByGetUsingModel')public String testGetUsingModel(BaseTest.Paper paper) { return paper.getContent();}/** * 通過 form 表單的方式獲取數據. 方法使用簡單類型進行接收 */@ResponseBody@PostMapping('/xssByFormPostUsingSimple')public String testFormPostUsingSimple(@RequestParam(name = 'content') String content) { return content;}/** * 通過 form 表單的方式獲取數據. 方法使用model進行參數接收 */@ResponseBody@PostMapping('/xssByFormPostUsingModel')public String testFormPostUsingModel(BaseTest.Paper paper) { return paper.getContent();}/** * 通過 request body 發送 json數據 */@ResponseBody@PostMapping('/xssByPostJsonBody')public String testPostJsonBody(@RequestBody BaseTest.Paper paper) { return paper.getContent();}

大家都知道,在spring mvc中處理請求的入口在 DispatcherServlet 類中,其中 doDispatch() 方法完成所有核心功能。在該主流程中,HandlerAdapter 將會對HTTP請求進行 Controller 的方法調用,以及對請求結果進行轉換,并封裝為DispatcherServlet 類需要的 ModelAndView 。在這里,由于使用注解的方式進行 Controller 定義,所以 HandlerAdapter 的實現類為 RequestMappingHandlerAdapter 。RequestMappingHandlerAdapter 類的 handle() 方法中,委托給 HandlerMethodArgumentResolver 對每個 Controller 的 方法的每個參數進行解析,反射調用 Controller 的 方法后,再 委托 HandlerMethodReturnValueHandler 對反射調用的返回值進行處理。

至此,本文的主角出現了,也就是 HandlerMethodArgumentResolver 。我們看下有關于本文的HandlerMethodArgumentResolver 類繼承關系。

springboot項目如何防止XSS攻擊

上面的常見controller定義方法的 參數解析(注意,這里是說方法那里的參數解析) 對應 HandlerMethodArgumentResolver 的關系如下圖:

springboot項目如何防止XSS攻擊

現在,我們已經知道了他們都由什么樣 HandlerMethodArgumentResolver 解析方法參數,我們繼續分析他們之前的共同點,并得到在哪里對http傳過來的數據進行XSS處理。

RequestResponseBodyMethodProcessor 是一個對request body的JSON數據反序列化的處理器,在 resolveArgument() 方法中,將會獲取合適的 org.springframework.http.converter.HttpMessageConverter 類對string數據進行反序列化處理。springboot 在初始化的時候,已經默認注冊了 jackson 的 MappingJackson2HttpMessageConverter ,并使用它對 JSON 數據進行反序列化操作。在 jackson 里面,JsonDeserializer 類 用于json數據的property的反序列化,因此,我們可以通過擴展 JsonDeserializer ,并在里面處理XSS即可。

對于 PathVariableMethodArgumentResolver、 RequestParamMethodArgumentResolver、 ServletModelAttributeMethodProcessor ,在 resolveArgument() 方法中,他們對需要對請求參數調用 DataBinder 類 對獲取到的參數類型轉換和數據綁定。對于類型轉換的過程,他們會使用 org.springframework.core.convert.converter.Converter 進行轉換。同樣,在SPRINGBOOT初始化的過程,也注冊了很多個默認的轉換器,我們可以注冊一個自定義轉換器,用于對數據進行xss處理。

3. 具體處理細節

抽象XSSCleaner,用于對string進行XSS處理

public interface XssCleaner { /** * 清理 html, 防止XSS * * @param html html * @return 清理后的數據 */ String clean(String html);}

使用JSOUP,做HTML節點的白名單處理

public class DefaultXssCleaner implements XssCleaner { public static final HtmlWhitelist WHITE_LIST = new HtmlWhitelist(); @Override public String clean(String html) {if (StringUtils.hasText(html)) { return Jsoup.clean(html, WHITE_LIST);}return html; } private static class HtmlWhitelist extends Whitelist {public HtmlWhitelist() { //定義標簽和屬性的白名單 addTags('a', 'b', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'div', 'span', 'embed', 'object', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'u', 'ul'); addAttributes('a', 'href', 'title', 'target'); addAttributes('blockquote', 'cite'); addAttributes('col', 'span'); addAttributes('colgroup', 'span'); addAttributes('img', 'align', 'alt', 'src', 'title'); addAttributes('ol', 'start'); addAttributes('q', 'cite'); addAttributes('table', 'summary'); addAttributes('td', 'abbr', 'axis', 'colspan', 'rowspan', 'width'); addAttributes('th', 'abbr', 'axis', 'colspan', 'rowspan', 'scope', 'width'); addAttributes('video', 'src', 'autoplay', 'controls', 'loop', 'muted', 'poster', 'preload'); addAttributes('object', 'width', 'height', 'classid', 'codebase'); addAttributes('param', 'name', 'value'); addAttributes('embed', 'src', 'quality', 'width', 'height', 'allowFullScreen', 'allowScriptAccess', 'flashvars', 'name', 'type', 'pluginspage'); addAttributes(':all', 'class', 'style', 'height', 'width', 'type', 'id', 'name'); addProtocols('blockquote', 'cite', 'http', 'https'); addProtocols('cite', 'cite', 'http', 'https'); addProtocols('q', 'cite', 'http', 'https');}@Overrideprotected boolean isSafeAttribute(String tagName, Element el, Attribute attr) { //不允許 javascript 開頭的 src 和 href if ('src'.equalsIgnoreCase(attr.getKey()) || 'href'.equalsIgnoreCase(attr.getKey())) {String value = attr.getValue();if (StringUtils.hasText(value) && value.toLowerCase().startsWith('javascript')) { return false;} } //允許 base64 的圖片內容 if ('img'.equals(tagName) && 'src'.equals(attr.getKey()) && attr.getValue().startsWith('data:;base64')) {return true; } return super.isSafeAttribute(tagName, el, attr);} }}

新增一個jackson的JsonDeserializer

/** * jackson的反序列化時的html xss過濾器 */public class JacksonXssCleanJsonDeserializer extends JsonDeserializer<String> { private final static Logger LOGGER = LoggerFactory.getLogger(JacksonXssCleanJsonDeserializer.class); private final XssCleaner xssCleaner; public JacksonXssCleanJsonDeserializer(XssCleaner xssCleaner) {this.xssCleaner = xssCleaner; } @Override public Class<?> handledType() {return String.class; } @Override public String deserialize(JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {// XSS cleanString text = p.getValueAsString();if (StringUtils.hasText(text) && XssCleanMarker.shouldClean()) { String cleanText = xssCleaner.clean(text); if (LOGGER.isDebugEnabled()) {LOGGER.debug('Json property value: [{}] cleaned up by JacksonXssCleanJsonDeserializer, current value is:{}.', text, cleanText); } return cleanText;}return text; }}

新增 Converter

/** * 對請求數據過濾xss */public class XssCleanConverter implements Converter<String, String> { private final Logger LOGGER = LoggerFactory.getLogger(XssCleanConverter.class); private XssCleaner xssCleaner; public XssCleanConverter(XssCleaner xssCleaner) {this.xssCleaner = xssCleaner; } @Override public String convert(String text) {if (StringUtils.hasText(text) && XssCleanMarker.shouldClean()) { String cleanText = xssCleaner.clean(text); if (LOGGER.isDebugEnabled()) {LOGGER.debug('request param [{}] cleaned up by XssCleanConverter, current value is:{}.', text, cleanText); } return cleanText;}return text; }}

對 JsonDeserializer 和 Converter 進行注冊

@Configuration@ConditionalOnProperty(value = XSS_PROPERTIES_ENABLED, havingValue = 'true', matchIfMissing = true)@ConditionalOnWebApplication@EnableConfigurationProperties({XssProperties.class})public class WebXssConfiguration implements WebMvcConfigurer { private XssProperties properties; public WebXssConfiguration(XssProperties properties) {this.properties = properties; } @Bean @ConditionalOnMissingBean public XssCleaner xssCleaner() {return new DefaultXssCleaner(); } @Bean @ConditionalOnClass(value = {ObjectMapper.class, Jackson2ObjectMapperBuilder.class}) public Jackson2ObjectMapperBuilderCustomizer jacksonXssCleanJsonDeserializerCustomer(XssCleaner xssCleaner) {return builder -> builder.deserializers(new JacksonXssCleanJsonDeserializer(xssCleaner)); } @Override public void addFormatters(FormatterRegistry registry) {XssCleaner xssCleaner = xssCleaner();registry.addConverter(new XssCleanConverter(xssCleaner)); } @Override public void addInterceptors(InterceptorRegistry registry) {XssCleanMarkerHandlerInterceptor handlerInterceptor = new XssCleanMarkerHandlerInterceptor(properties);registry.addInterceptor(handlerInterceptor); }}

上面是XSS處理的核心代碼。處理XSS處理,還進行了一些擴展,比如 http path 路徑的過濾 和 一些使能控制。

完整的代碼可以參考倉庫:倉庫地址

以上就是springboot項目如何防止XSS攻擊的詳細內容,更多關于springboot防止XSS攻擊的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
主站蜘蛛池模板: 上海橡胶接头_弹簧减震器_金属软接头厂家-上海淞江集团 | 结晶点测定仪-润滑脂滴点测定仪-大连煜烁 | 苏州西装定制-西服定制厂家-职业装定制厂家-尺品服饰西装定做公司 | 青岛空压机,青岛空压机维修/保养,青岛空压机销售/出租公司,青岛空压机厂家电话 | 电竞馆加盟,沈阳网吧加盟费用选择嘉棋电竞_售后服务一体化 | 汝成内控-行政事业单位内部控制管理服务商 | 空调风机,低噪声离心式通风机,不锈钢防爆风机,前倾皮带传动风机,后倾空调风机-山东捷风风机有限公司 | 全温恒温摇床-水浴气浴恒温摇床-光照恒温培养摇床-常州金坛精达仪器制造有限公司 | 超声波气象站_防爆气象站_空气质量监测站_负氧离子检测仪-风途物联网 | 学校用栓剂模,玻璃瓶轧盖钳,小型安瓿熔封机,实验室安瓿熔封机-长沙中亚制药设备有限公司 | 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 丹尼克尔拧紧枪_自动送钉机_智能电批_柔性振动盘_螺丝供料器品牌 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 影视模板素材_原创专业影视实拍视频素材-8k像素素材网 | 电动卫生级调节阀,电动防爆球阀,电动软密封蝶阀,气动高压球阀,气动对夹蝶阀,气动V型调节球阀-上海川沪阀门有限公司 | 学习安徽网| 天津蒸汽/热水锅炉-电锅炉安装维修直销厂家-天津鑫淼暖通设备有限公司 | 光泽度计_测量显微镜_苏州压力仪_苏州扭力板手维修-苏州日升精密仪器有限公司 | 快速卷帘门_硬质快速卷帘门-西朗门业 | 回转窑-水泥|石灰|冶金-巩义市瑞光金属制品有限责任公司 | 洗瓶机厂家-酒瓶玻璃瓶冲瓶机-瓶子烘干机-封口旋盖压盖打塞机_青州惠联灌装机械 | 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 合肥弱电工程_安徽安防工程_智能化工程公司-合肥雷润 | 环氧铁红防锈漆_环氧漆_无溶剂环氧涂料_环氧防腐漆-华川涂料 | 最新范文网_实用的精品范文美文网 | 渣油泵,KCB齿轮泵,不锈钢齿轮泵,重油泵,煤焦油泵,泊头市泰邦泵阀制造有限公司 | 低气压试验箱_高低温低气压试验箱_低气压实验箱 |林频试验设备品牌 | 千淘酒店差旅平台-中国第一家针对TMC行业的酒店资源供应平台 | 恒温振荡混匀器-微孔板振荡器厂家-多管涡旋混匀器厂家-合肥艾本森(www.17world.net) | 电镀整流器_微弧氧化电源_高频电解电源_微弧氧化设备厂家_深圳开瑞节能 | 锂电叉车,电动叉车_厂家-山东博峻智能科技有限公司 | 老房子翻新装修,旧房墙面翻新,房屋防水补漏,厨房卫生间改造,室内装潢装修公司 - 一修房屋快修官网 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 海鲜池-专注海鲜鱼缸、移动海鲜缸、饭店鱼缸设计定做-日晟水族厂家 | 动物麻醉机-数显脑立体定位仪-北京易则佳科技有限公司 | 布袋式除尘器|木工除尘器|螺旋输送机|斗式提升机|刮板输送机|除尘器配件-泊头市德佳环保设备 | 房在线-免费房产管理系统软件-二手房中介房屋房源管理系统软件 | 电动车头盔厂家_赠品头盔_安全帽批发_山东摩托车头盔—临沂承福头盔 | 硫化罐-胶管硫化罐-山东鑫泰鑫智能装备有限公司 | 法兰连接型电磁流量计-蒸汽孔板节流装置流量计-北京凯安达仪器仪表有限公司 |