最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot中使用過濾器,jsoup過濾XSS腳本詳解

 更新時(shí)間:2021年12月17日 16:52:31   作者:千山暮雪CN  
這篇文章主要介紹了springboot中使用過濾器,jsoup過濾XSS腳本詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

springboot使用過濾器,jsoup過濾XSS腳本

  • 背景:略
  • 目標(biāo):完成request請(qǐng)求中的腳本過濾
  • 技術(shù):filter,jsoup,requestWapper

1.把可能包含腳本的參數(shù)位置分析一下

  • post/put/delete: 請(qǐng)求的參數(shù)中,有可能是表單提交、也有可能是使用了@requestBody注解,那么參數(shù)就是json格式,位于request的流中。
  • get/options等:可能存在于url參數(shù)中,也有可能是表單提交的預(yù)請(qǐng)求中,所以一般在能想到的位置都有可能存在,包括header中。

2.分析實(shí)現(xiàn)過程

2.1首先要從request請(qǐng)求中將各個(gè)需要過濾位置的參數(shù)取出來(lái)

2.2然后將參數(shù)取出來(lái)進(jìn)行過濾

2.3將過濾后的參數(shù)重新包裝成request傳遞下去

2.4在這期間,

  • 需要準(zhǔn)備好jsoup過濾腳本的工具類;
  • 需要自定義一個(gè)過濾器,并且在過濾器中添加匹配條件,如:那些url不需要過濾,那些請(qǐng)求方式必須進(jìn)行過濾;
  • 對(duì)過濾器進(jìn)行配置,是否開啟,設(shè)置在整個(gè)過濾器鏈中的位置,設(shè)置過濾的白名單或者黑名單
  • 所以就很清晰了我們過濾需要哪些類,哪些配置了

一個(gè)filter

一個(gè)requestWapper

一個(gè)jsoup工具類

一個(gè)filter的配置類

2.5進(jìn)行數(shù)據(jù)測(cè)試

3.代碼實(shí)現(xiàn)過程

3.1.jsoup依賴:

<!--screen xss --> 
<dependency> 
<groupId>org.jsoup</groupId> 
<artifactId>jsoup</artifactId> 
<version>1.9.2</version> 
</dependency>

3.2jsoup工具類:JsoupUtil

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.safety.Whitelist;   
import java.io.FileNotFoundException; 
import java.io.IOException;  
 
/**
* @Auther: qianshanmuxue
* @Date: 2019/2/27 19:32
* @Description: xss Illegal label filtering
*/
 
public class JsoupUtil {   
private static final Whitelist whitelist = Whitelist.simpleText();//jsoup白名單種類,有四種,每一種針對(duì)的標(biāo)簽類型不一樣,具體的可以ctrl+左鍵點(diǎn)擊simpleText,在jsoup源碼中有響應(yīng)的注釋和標(biāo)簽名單
//add myself white list label
private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
static {
whitelist.addAttributes(":all", "style").addTags("p").addTags("strong");//將自定義標(biāo)簽添加進(jìn)白名單,除開白名單之外的標(biāo)簽都會(huì)被過濾
whitelist.preserveRelativeLinks(true);//這個(gè)配置的意思的過濾如果找不到成對(duì)的標(biāo)簽,就只過濾單個(gè)標(biāo)簽,而不用把后面所有的文本都進(jìn)行過濾。
//(之前在這個(gè)問題上折騰了很久,當(dāng)<script>標(biāo)簽只有一個(gè)時(shí),會(huì)<script>標(biāo)簽后面的數(shù)據(jù)全部過濾)
}
 
public static String clean(String content) { //過濾方法
return Jsoup.clean(content, "", whitelist, outputSettings);
}
 
//test main
public static void main(String[] args) throws FileNotFoundException, IOException {
String text = "<a href=\"http://www.baidu.com/a\" onclick=\"alert(1);\"><strong><p>sss</p></strong></a><script>alert(0);</script>sss";
System.out.println(clean(text));
}
}

3.3request包裝類XssHttpServletRequestWrapper

import java.io.*;
import java.util.*;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import com.xxx.utils.JsoupUtil;
import org.jsoup.nodes.Document;
import org.springframework.util.StringUtils;
 
/**
 * @Auther: qianshanmuxue
 * @Date: 2019/2/27 16:24
 * @Description:request wapper use to get request parameter and request bdoy data and wapper another request 
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { //因?yàn)槲覀冃枰@取request中的數(shù)據(jù),所以需要繼承java底層中HttpServletRequestWrapper這個(gè)類,重寫父類中的某些方法,獲取相應(yīng)位置的參數(shù)
    private HttpServletRequest orgRequest = null;
    private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }
 
    @Override 
    public ServletInputStream getInputStream() throws IOException {//get  
        BufferedReader br = new BufferedReader(new InputStreamReader(orgRequest.getInputStream()));
        String line = br.readLine();
        String result = "";
        if (line != null) {
            result += clean(line);
        } 
        return new WrappedServletInputStream(new ByteArrayInputStream(result.getBytes()));
    }
    @Override
    public String getParameter(String name) {
        if (("content".equals(name) || name.endsWith("WithHtml"))) {
            return super.getParameter(name);
        }
        name = clean(name);
        String value = super.getParameter(name);
        if (!StringUtils.isEmpty(value)) {
            value = clean(value);
        }
        return value;
    }
 
    @Override
    public Map getParameterMap() {
        Map map = super.getParameterMap();
        // 返回值Map
        Map<String, String> returnMap = new HashMap<String, String>();
        Iterator entries = map.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (int i = 0; i < values.length; i++) {
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length() - 1);
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, clean(value).trim());
        }
        return returnMap;
    }
 
    @Override
    public String[] getParameterValues(String name) {
        String[] arr = super.getParameterValues(name);
        if (arr != null) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] = clean(arr[i]);
            }
        }
        return arr;
    }
 
    /**
     * get org request
     *
     * @return
     */
    public HttpServletRequest getOrgRequest() {
        return orgRequest;
    }
 
    /**
     * wapper request
     */
    public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
        if (req instanceof XssHttpServletRequestWrapper) {
            return ((XssHttpServletRequestWrapper) req).getOrgRequest();
        }
        return req;
    }
 
    public String clean(String content) {
        String result = JsoupUtil.clean(content);
        return result;
    }
 
    private class WrappedServletInputStream extends ServletInputStream {
        public void setStream(InputStream stream) {
            this.stream = stream;
        }
 
        private InputStream stream; 
        public WrappedServletInputStream(InputStream stream) {
            this.stream = stream;
        }
 
        @Override
        public int read() throws IOException {
            return stream.read();
        }
 
        @Override
        public boolean isFinished() {
            return true;
        }
 
        @Override
        public boolean isReady() {
            return true;
        }
 
        @Override
        public void setReadListener(ReadListener readListener) { 
        }
    }
}

3.4filter-XssFilter

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils; 
import java.io.IOException; 
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import javax.servlet.Filter;
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;
import javax.servlet.http.HttpServletResponse;
 
/**
 * @Auther: qianshanmuxue
 * @Date: 2019/2/27 16:25
 * @Description:
 */
//@WebFilter
//@Component   在這里可以不用這個(gè)注解,以為后面我們會(huì)在config中去配置這個(gè)filter,在這里只需要實(shí)現(xiàn) Filter  接口實(shí)現(xiàn)相應(yīng)的方法就ok
public class XssFilter implements Filter {
    private static boolean IS_INCLUDE_RICH_TEXT = false;//用于接收配置中的參數(shù),決定這個(gè)過濾器是否開啟
    public List<String> excludes = new ArrayList<String>();//用于接收配置中的參數(shù),決定哪些是不需要過濾的url(在這里,也可以修改handleExcludeURL()方法中相應(yīng)的代碼,使其變更為只需要過濾的url)
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        if (handleExcludeURL(req, resp)) {
            chain.doFilter(request, response);
            return;
        }
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
        chain.doFilter(xssRequest, response);
    }
/**
*此方法是決定對(duì)當(dāng)前url是否執(zhí)行過濾,
*在這里沒有使用請(qǐng)求方法(post/put)來(lái)匹配,因?yàn)樵诒卷?xiàng)目中使用url匹配更適合(因?yàn)間et和其他請(qǐng)求方式也需要進(jìn)行過濾),如果你有興趣可以把這個(gè)方法更改為匹配請(qǐng)求方法進(jìn)行過濾
**/
    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
        if ((excludes == null || excludes.isEmpty())&&IS_INCLUDE_RICH_TEXT) {
            return false;
        }
        String url = request.getServletPath();
        for (String pattern : excludes) {
            Pattern p = Pattern.compile("^" + pattern);
            Matcher m = p.matcher(url);
            if (m.find()) {
                return true;
            }
        }
        return false;
    }
/**
 *過濾器初始化,從配置類中獲取參數(shù),用于初始化兩個(gè)參數(shù)(是否開啟,排除指定的url list)
 *
 */
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        String isIncludeRichText = arg0.getInitParameter("isIncludeRichText");
        if (StringUtils.isNotBlank(isIncludeRichText)) {
            IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
        }
 
        String temp = arg0.getInitParameter("excludes");
        if (temp != null) {
            String[] url = temp.split(",");
            for (int i = 0; url != null && i < url.length; i++) {
                excludes.add(url[i]);
            }
        }
    }
 
    @Override
    public void destroy() {
    }
}

3.5filter的配置類:XssConfig

import com.xxx.filter.XssFilter;
import com.google.common.collect.Maps;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; 
import java.util.Map;
 
/**
 * @Auther: qianshanmuxue
 * @Date: 2019/2/27 16:49
 * @Description: xss filter config
 */
@Configuration
public class XssConfig {
    @Bean
    public FilterRegistrationBean xssFilterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new XssFilter());
        filterRegistrationBean.setOrder(1);//filter order ,set it first
        filterRegistrationBean.setEnabled(true);
        filterRegistrationBean.addUrlPatterns("/*"); //set filter all url mapping
        Map<String, String> initParameters = Maps.newHashMap();
        initParameters.put("excludes", "/oauth/token");///white list url
        initParameters.put("isIncludeRichText", "true");//enable or disable
        filterRegistrationBean.setInitParameters(initParameters);
        return filterRegistrationBean;
    }
}

調(diào)試截圖:

請(qǐng)求:

程序截圖:

運(yùn)行結(jié)果:

可以看到body中 的腳本已經(jīng)被過濾了,

然后其他的截圖我就不發(fā)了,還有一種思路就是在過濾器中把字符轉(zhuǎn)義。

感謝luckpet大佬的提示

1 BufferedReader 使用完需要關(guān)閉 ;

2 對(duì)于一些拿postman等工具的朋友,拼接json的話會(huì)有換行 這里result += clean(line); 需要改成: while((line = br.readLine()) != null){ if (line != null) { result += line; } }

使用jsoup防止XSS攻擊

前陣子項(xiàng)目國(guó)測(cè)后,打開一個(gè)項(xiàng)目頁(yè)面,莫名其妙彈出xss,搜了全局也沒找到alert("xss"),問了一下項(xiàng)目經(jīng)理,原來(lái)是國(guó)測(cè)做防注入的時(shí)候,在添加數(shù)據(jù)的時(shí)候做的,一臉懵逼。

查了一下資料,以前做項(xiàng)目的時(shí)候都沒想到這個(gè)問題,如果保存一段script腳本,查數(shù)據(jù)的時(shí)候,這段腳本就會(huì)被執(zhí)行,這東西后果挺嚴(yán)重啊,如果是在桌面外彈框,執(zhí)行個(gè)挖礦腳本,這玩意不得了啊,厲害,長(zhǎng)知識(shí)了。。。

<dependency>
 <groupId>org.jsoup</groupId>
 <artifactId>jsoup</artifactId>
 <version>1.11.3</version>
</dependency>

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java各種類型對(duì)象占用內(nèi)存情況分析

    java各種類型對(duì)象占用內(nèi)存情況分析

    這篇文章主要介紹了java各種類型對(duì)象占用內(nèi)存情況分析,對(duì)內(nèi)存或者性能優(yōu)化感興趣的同學(xué),一定要看一下
    2021-04-04
  • java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出

    java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出

    這篇文章主要介紹了java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出的方法和具體示例,有需要的小伙伴可以參考下。
    2015-06-06
  • springboot如何通過注解實(shí)現(xiàn)多線程

    springboot如何通過注解實(shí)現(xiàn)多線程

    在Spring Boot中實(shí)現(xiàn)異步方法時(shí),如果直接在調(diào)用類中使用`@Async`注解,可能會(huì)導(dǎo)致異步失敗,正確的做法是將實(shí)現(xiàn)異步的方法放在一個(gè)獨(dú)立的類中,并通過Spring生成的bean來(lái)調(diào)用這個(gè)方法,這樣可以成功實(shí)現(xiàn)異步
    2024-12-12
  • SpringCloud Alibaba項(xiàng)目實(shí)戰(zhàn)之nacos-server服務(wù)搭建過程

    SpringCloud Alibaba項(xiàng)目實(shí)戰(zhàn)之nacos-server服務(wù)搭建過程

    Nacos 是阿里巴巴推出來(lái)的一個(gè)新開源項(xiàng)目,這是一個(gè)更易于構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺(tái)。本章節(jié)重點(diǎn)給大家介紹SpringCloud Alibaba項(xiàng)目實(shí)戰(zhàn)之nacos-server服務(wù)搭建過程,感興趣的朋友一起看看吧
    2021-06-06
  • 在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解

    在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解

    這篇文章主要介紹了在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-12-12
  • java關(guān)于String.split("|")的使用方式

    java關(guān)于String.split("|")的使用方式

    這篇文章主要介紹了java關(guān)于String.split("|")的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java子線程解決獲取主線程的request對(duì)象問題

    java子線程解決獲取主線程的request對(duì)象問題

    這篇文章主要介紹了java子線程解決獲取主線程的request對(duì)象問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • SpringBoot集成drools的實(shí)現(xiàn)示例

    SpringBoot集成drools的實(shí)現(xiàn)示例

    本文主要介紹了SpringBoot集成drools的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • springboot配置開發(fā)和測(cè)試環(huán)境并添加啟動(dòng)路徑方式

    springboot配置開發(fā)和測(cè)試環(huán)境并添加啟動(dòng)路徑方式

    這篇文章主要介紹了springboot配置開發(fā)和測(cè)試環(huán)境并添加啟動(dòng)路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java仿12306圖片驗(yàn)證碼

    Java仿12306圖片驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了Java仿12306的圖片驗(yàn)證碼的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評(píng)論

石景山区| 文登市| 延寿县| 平陆县| 永安市| 藁城市| 新沂市| 磐安县| 辽阳县| 曲阜市| 嘉鱼县| 鄂州市| 桑日县| 喀喇沁旗| 南投县| 沙坪坝区| 庄浪县| 科技| 遂平县| 交城县| 和顺县| 永川市| 文安县| 榆林市| 资源县| 南涧| 湖口县| 兴隆县| 宜良县| 缙云县| 融水| 孟连| 云南省| 夏津县| 汶川县| 大安市| 益阳市| 隆子县| 图木舒克市| 治多县| 阳高县|