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

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

springboot項目如何防止XSS攻擊

瀏覽:74日期: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
相關文章:
主站蜘蛛池模板: 电销卡_稳定企业大语音卡-归属地可选-世纪通信 | 气动隔膜阀_气动隔膜阀厂家_卫生级隔膜阀价格_浙江浙控阀门有限公司 | 塑胶跑道_学校塑胶跑道_塑胶球场_运动场材料厂家_中国塑胶跑道十大生产厂家_混合型塑胶跑道_透气型塑胶跑道-广东绿晨体育设施有限公司 | 车牌识别道闸_停车场收费系统_人脸识别考勤机_速通门闸机_充电桩厂家_中全清茂官网 | 热回收盐水机组-反应釜冷水机组-高低温冷水机组-北京蓝海神骏科技有限公司 | 杭州代理记账费用-公司注销需要多久-公司变更监事_杭州福道财务管理咨询有限公司 | 垃圾压缩设备_垃圾处理设备_智能移动式垃圾压缩设备--山东明莱环保设备有限公司 | 美国PARKER齿轮泵,美国PARKER柱塞泵,美国PARKER叶片泵,美国PARKER电磁阀,美国PARKER比例阀-上海维特锐实业发展有限公司二部 | 刹车盘机床-刹车盘生产线-龙口亨嘉智能装备 | 消防设施操作员考试报名时间,报名入口,报考条件 | 便携式表面粗糙度仪-彩屏硬度计-分体式粗糙度仪-北京凯达科仪科技有限公司 | AGV叉车|无人叉车|AGV智能叉车|AGV搬运车-江西丹巴赫机器人股份有限公司 | 南京办公用品网-办公文具用品批发-打印机耗材采购 | 洛阳永磁工业大吊扇研发生产-工厂通风降温解决方案提供商-中实洛阳环境科技有限公司 | 密集架-手摇-智能-移动-价格_内蒙古档案密集架生产厂家 | 乐之康护 - 专业护工服务平台,提供医院陪护-居家照护-居家康复 | 法钢特种钢材(上海)有限公司 - 耐磨钢板、高强度钢板销售加工 阀门智能定位器_电液动执行器_气动执行机构-赫尔法流体技术(北京)有限公司 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | 镀锌角钢_槽钢_扁钢_圆钢_方矩管厂家_镀锌花纹板-海邦钢铁(天津)有限公司 | 金现代信息产业股份有限公司--数字化解决方案供应商 | 大学食堂装修设计_公司餐厅效果图_工厂食堂改造_迈普装饰 | 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | 间甲酚,间甲酚厂家-山东祥东新材料| 吉林污水处理公司,长春工业污水处理设备,净水设备-长春易洁环保科技有限公司 | 智能案卷柜_卷宗柜_钥匙柜_文件流转柜_装备柜_浙江福源智能科技有限公司 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 | 济南冷库安装-山东冷库设计|建造|冷库维修-山东齐雪制冷设备有限公司 | 深圳APP开发公司_软件APP定制开发/外包制作-红匣子科技 | 黄石妇科医院_黄石东方女子医院_黄石东方妇产医院怎么样 | 卡诺亚轻高定官网_卧室系统_整家定制_定制家居_高端定制_全屋定制加盟_定制家具加盟_定制衣柜加盟 | 螺杆式冷水机-低温冷水机厂家-冷冻机-风冷式-水冷式冷水机-上海祝松机械有限公司 | 河北中仪伟创试验仪器有限公司是专业生产沥青,土工,水泥,混凝土等试验仪器的厂家,咨询电话:13373070969 | 家用净水器代理批发加盟_净水机招商代理_全屋净水器定制品牌_【劳伦斯官网】 | 英思科GTD-3000EX(美国英思科气体检测仪MX4MX6)百科-北京嘉华众信科技有限公司 | 京马网,京马建站,网站定制,营销型网站建设,东莞建站,东莞网站建设-首页-京马网 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | CXB船用变压器-JCZ系列制动器-HH101船用铜质开关-上海永上船舶电器厂 | 361°官方网站| KBX-220倾斜开关|KBW-220P/L跑偏开关|拉绳开关|DHJY-I隔爆打滑开关|溜槽堵塞开关|欠速开关|声光报警器-山东卓信有限公司 | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 | 三轴曲线机-端子插拔力试验机|华杰仪器|