Java解決xss轉(zhuǎn)義導(dǎo)致轉(zhuǎn)碼的問題
一、xss簡(jiǎn)介
人們經(jīng)常將跨站腳本攻擊(Cross Site Scripting)縮寫為CSS,但這會(huì)與層疊樣式表(Cascading Style Sheets,CSS)的縮寫混淆。因此,有人將跨站腳本攻擊縮寫為XSS??缯灸_本攻擊(XSS),是最普遍的Web應(yīng)用安全漏洞。這類漏洞能夠使得攻擊者嵌入惡意腳本代碼到正常用戶會(huì)訪問到的頁(yè)面中,當(dāng)正常用戶訪問該頁(yè)面時(shí),則可導(dǎo)致嵌入的惡意腳本代碼的執(zhí)行,從而達(dá)到惡意攻擊用戶的目的。
攻擊者可以使用戶在瀏覽器中執(zhí)行其預(yù)定義的惡意腳本,其導(dǎo)致的危害可想而知,如劫持用戶會(huì)話,插入惡意內(nèi)容、重定向用戶、使用惡意軟件劫持用戶瀏覽器、繁殖XSS蠕蟲,甚至破壞網(wǎng)站、修改路由器配置信息等。
二、解決方式
解決方式有很多,這里介紹將內(nèi)容經(jīng)過轉(zhuǎn)義然后再存儲(chǔ)到服務(wù)器上。
package com.wssnail.xss.config; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import java.io.IOException; import java.util.List; import java.util.ListIterator; /** * @author 熟透的蝸牛 * @version 1.0 * @description: 配置xss攻擊過濾 * @date 2023/8/14 23:48 */ @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { @Override protected void extendMessageConverters(List<HttpMessageConverter<?>> messageConverters) { /** * 替換默認(rèn)的MappingJackson2HttpMessageConverter,過濾(json請(qǐng)求參數(shù))xss */ ListIterator<HttpMessageConverter<?>> listIterator = messageConverters.listIterator(); while (listIterator.hasNext()) { HttpMessageConverter<?> next = listIterator.next(); if (next instanceof MappingJackson2HttpMessageConverter) { listIterator.remove(); break; } } messageConverters.add(getMappingJackson2HttpMessageConverter()); } public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() { // 創(chuàng)建自定義ObjectMapper SimpleModule module = new SimpleModule(); module.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class)); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.getApplicationContext()).build(); objectMapper.registerModule(module); // 創(chuàng)建自定義消息轉(zhuǎn)換器 MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper); return mappingJackson2HttpMessageConverter; } /** * 添加默認(rèn)請(qǐng)求類型 */ @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.ignoreAcceptHeader(true). defaultContentType(MediaType.APPLICATION_JSON, MediaType.TEXT_XML, MediaType.APPLICATION_XML); } } /** * @author 熟透的蝸牛 * @version 1.0 * @description: 對(duì)xss進(jìn)行過濾 * @date 2023/8/14 23:49 */ class JsonHtmlXssDeserializer extends JsonDeserializer<String> { public JsonHtmlXssDeserializer(Class<String> string) { super(); } @Override public Class<String> handledType() { return String.class; } @Override public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { String value = jsonParser.getValueAsString(); if (!StringUtils.isEmpty(value)) { return StringEscapeUtils.escapeHtml4(value); } return value; } }
請(qǐng)求如上接口,經(jīng)過轉(zhuǎn)義之后,存到數(shù)據(jù)庫(kù)的內(nèi)容就不再是我們傳參的數(shù)據(jù),而是經(jīng)過轉(zhuǎn)義的內(nèi)容
經(jīng)過查詢之后內(nèi)容就回顯成轉(zhuǎn)義之后的內(nèi)容了,如下圖
三、解決轉(zhuǎn)義的內(nèi)容
先說一下思路,自定義一個(gè)注解,作用在實(shí)體類或者字段上,當(dāng)查詢的時(shí)候,在數(shù)據(jù)返回之前,對(duì)數(shù)據(jù)進(jìn)行反轉(zhuǎn)義。下面直接上代碼。
自定義注解
package com.wssnail.xss.annotation; import java.lang.annotation.*; @Target({ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface StringEscapeCode { }
工具類
package com.wssnail.xss.utils; import com.wssnail.xss.annotation.StringEscapeCode; import org.apache.commons.text.StringEscapeUtils; import java.lang.reflect.Field; /** * @author 熟透的蝸牛 * @version 1.0 * @description: 配置字符串格式文本處理工具 * @date 2023/8/14 23:50 */ public class StringEscapeCodeUtil { public static void stringEscape(Class<?> clazz, Object obj) throws IllegalAccessException { StringEscapeCode declaredAnnotation = clazz.getDeclaredAnnotation(StringEscapeCode.class); if (declaredAnnotation != null) { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (fields[i].getGenericType().toString().endsWith("String")) { //有注解,設(shè)置字段 fields[i].setAccessible(true); String value = StringEscapeUtils.unescapeHtml4((String) fields[i].get(obj)); fields[i].set(obj, value); } } } else { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { StringEscapeCode annotation = fields[i].getAnnotation(StringEscapeCode.class); if (fields[i].getGenericType().toString().endsWith("String")) { if (annotation != null) { //有注解,設(shè)置字段 fields[i].setAccessible(true); String value = StringEscapeUtils.unescapeHtml4((String) fields[i].get(obj)); fields[i].set(obj, value); } } } } } }
實(shí)際使用
package com.wssnail.xss.annotation; import java.lang.annotation.*; /** * @author 熟透的蝸牛 * @version 1.0 * @description: 自定義注解 * 使用方法 將該注解添加到類上,或者屬性上,只有作用在、string類型的屬性上,注解才會(huì)生效 * @date 2023/8/15 0:13 */ @Target({ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface StringEscapeCode { }
public User getById(Integer id) { try { User user = userMapper.findByID(id); Class<? extends User> clazz = user.getClass(); StringEscapeCodeUtil.unStringEscape(clazz, user); return user; } catch (IllegalAccessException e) { throw new RuntimeException(e); } }
然后查詢的時(shí)候,就會(huì)正常顯示內(nèi)容了。
完整代碼 xss-demo: 解決xss轉(zhuǎn)義亂碼返回的問題
到此這篇關(guān)于Java解決xss轉(zhuǎn)義導(dǎo)致轉(zhuǎn)碼的問題的文章就介紹到這了,更多相關(guān)Java xss轉(zhuǎn)義內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-Plus進(jìn)階分頁(yè)與樂觀鎖插件及通用枚舉和多數(shù)據(jù)源詳解
這篇文章主要介紹了Mybatis-Plus的分頁(yè)插件與樂觀鎖插件還有通用枚舉和多數(shù)據(jù)源的相關(guān)介紹,文中代碼附有詳細(xì)的注釋,感興趣的朋友來看看吧2022-03-03Java調(diào)用setStroke()方法設(shè)置筆畫屬性的語(yǔ)法
這篇文章主要介紹了Java調(diào)用setStroke()方法設(shè)置筆畫屬性的語(yǔ)法,如何改變線條的粗細(xì)、虛實(shí)和定義線段端點(diǎn)的形狀、風(fēng)格等,需要的朋友可以參考下2017-09-09SpringCloud 服務(wù)負(fù)載均衡和調(diào)用 Ribbon、OpenFeign的方法
這篇文章主要介紹了SpringCloud 服務(wù)負(fù)載均衡和調(diào)用 Ribbon、OpenFeign的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Java運(yùn)用SWT插件編寫桌面記事本應(yīng)用程序
這篇文章主要為大家介紹了一個(gè)Java項(xiàng)目實(shí)戰(zhàn),一步步教你實(shí)現(xiàn)記事本,步驟很詳細(xì),運(yùn)用SWT插件手把手編寫記事本,感興趣的小伙伴們可以參考一下2016-01-01