欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java過(guò)濾XSS腳本攻擊詳細(xì)代碼示例

 更新時(shí)間:2024年10月11日 11:41:45   作者:IAmZRH  
這篇文章主要介紹了Java過(guò)濾XSS腳本攻擊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

背景

之前公司信息安全部門對(duì)公司項(xiàng)目進(jìn)行網(wǎng)絡(luò)安全升級(jí)時(shí),發(fā)現(xiàn)項(xiàng)目里可能會(huì)出現(xiàn)XSS腳本攻擊漏洞,所以就需要對(duì)其參數(shù)進(jìn)行過(guò)濾攔截。

XSS

百度百科:XSS攻擊全稱:cross site scripting(這里是為了和CSS區(qū)分,所以叫XSS),跨站腳本攻擊(XSS),是最普遍的Web應(yīng)用安全漏洞。這類漏洞能夠使得攻擊者嵌入惡意腳本代碼到正常用戶會(huì)訪問(wèn)到的頁(yè)面中,當(dāng)正常用戶訪問(wèn)該頁(yè)面時(shí),則可導(dǎo)致嵌入的惡意腳本代碼的執(zhí)行,從而達(dá)到惡意攻擊用戶的目的。攻擊者可以使用戶在瀏覽器中執(zhí)行其預(yù)定義的惡意腳本,其導(dǎo)致的危害可想而知,如劫持用戶會(huì)話,插入惡意內(nèi)容、重定向用戶、使用惡意軟件劫持用戶瀏覽器、繁殖XSS蠕蟲,甚至破壞網(wǎng)站、修改路由器配置信息等。

  • xss漏洞攻擊分為三種:
    • 反射性XSS攻擊:前端在發(fā)送請(qǐng)求時(shí),在url參數(shù)里攜帶一些腳本命令,然后等服務(wù)端把腳本在反射給瀏覽器執(zhí)行腳本代碼,進(jìn)行XSS漏洞攻擊
    • 存儲(chǔ)性XSS攻擊:和反射性XSS漏洞攻擊相似,但是服務(wù)器會(huì)進(jìn)行持久化保存腳本命令,后續(xù)用戶訪問(wèn)該數(shù)據(jù)時(shí)持久性進(jìn)行XSS漏洞攻擊
    • DOS性XSS攻擊:和服務(wù)端沒(méi)有交互,靠瀏覽器的DOM解析進(jìn)行XSS攻擊

Java過(guò)濾

  • 預(yù)防XSS漏洞攻擊除了web端進(jìn)行解析過(guò)濾外,也還需要服務(wù)端進(jìn)行校驗(yàn)過(guò)濾
  • 本次使用springboot項(xiàng)目中過(guò)濾器進(jìn)行對(duì)前端傳來(lái)的參數(shù)進(jìn)行過(guò)濾攔截
/**
 * springboot注冊(cè)過(guò)濾器
 *
 * @author: zrh
 * @date: 2021-11-17
 */

@Configuration
public class XssFilterConfig {

    @Bean
    public FilterRegistrationBean xssFilterRegistrationBean () {
        FilterRegistrationBean initXssFilterBean = new FilterRegistrationBean();
        // 設(shè)置自定義過(guò)濾器
        initXssFilterBean.setFilter(new XssFilter());
        // 設(shè)置優(yōu)先級(jí)(值越低,優(yōu)先級(jí)越高)
        initXssFilterBean.setOrder(1);
        // 設(shè)置過(guò)濾路徑
        initXssFilterBean.addUrlPatterns("/*");
        // 設(shè)置過(guò)濾器名稱
        initXssFilterBean.setName("XSS_filter");
        // 設(shè)置過(guò)濾器作用范圍(可以配置多種,這里指定過(guò)濾請(qǐng)求資源)
        initXssFilterBean.setDispatcherTypes(DispatcherType.REQUEST);
        return initXssFilterBean;
    }
}
  • spring項(xiàng)目中可以使用web.xml定義過(guò)濾器,springboot中沒(méi)有web.xml配置文件,那么就可以使用FilterRegistrationBean類把過(guò)濾器實(shí)例注冊(cè)到容器
/**
 * 自定義過(guò)濾器
 *
 * @author: zrh
 * @date: 2021-11-17
 */
@Slf4j
public class XssFilter implements Filter {

    @Override
    public void init (FilterConfig filterConfig) {
        // 初始化調(diào)用
    }

    @Override
    public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        final XssHttpServletRequestWrapper requestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest);
        filterChain.doFilter(requestWrapper, servletResponse);
    }

    @Override
    public void destroy () {
        // 銷毀調(diào)用
    }
}
/**
 * 重寫請(qǐng)求參數(shù)過(guò)濾
 *
 * @author: zrh
 * @date: 2021-11-17
 */
@Slf4j
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpServletRequestWrapper (HttpServletRequest request) {
        super(request);
    }

    /**
     * 對(duì)GET請(qǐng)求中參數(shù)進(jìn)行過(guò)濾校驗(yàn)
     *
     * @param name
     * @return
     */
    @Override
    public String[] getParameterValues (String name) {
        String[] values = super.getParameterValues(name);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] cleanParams = new String[count];
        for (int i = 0; i < count; i++) {
            cleanParams[i] = String.valueOf(XssUtil.filterParam(values[i]));
            log.info("getParameterValues -> name:{},過(guò)濾前參數(shù):{},過(guò)濾后參數(shù):{}", name, values[i], cleanParams[i]);
        }
        return cleanParams;
    }

    /**
     * 對(duì)POST請(qǐng)求頭進(jìn)行參數(shù)過(guò)濾校驗(yàn)
     *
     * @param header
     * @return
     */
    @Override
    public Enumeration getHeaders (String header) {
        final String value = super.getHeader(header);
        final LinkedList list = new LinkedList();
        if (value != null) {
            final Object param = XssUtil.filterParam(value);
            list.addFirst(param);
            log.info("getHeaders -> header:{},過(guò)濾前參數(shù):{},過(guò)濾后參數(shù):{}", header, value, param);
        }
        return Collections.enumeration(list);
    }

    /**
     * 對(duì)POST請(qǐng)求中body參數(shù)進(jìn)行校驗(yàn)
     *
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream () throws IOException {
        final ByteArrayInputStream stream = new ByteArrayInputStream(inputHandlers(super.getInputStream()).getBytes());
        return new ServletInputStream() {
            @Override
            public int read () {
                return stream.read();
            }

            @Override
            public boolean isFinished () {
                return false;
            }

            @Override
            public boolean isReady () {
                return false;
            }

            @Override
            public void setReadListener (ReadListener readListener) {
            }
        };
    }

    /**
     * 解析請(qǐng)求流參數(shù)
     *
     * @param servletInputStream
     * @return
     */
    public String inputHandlers (ServletInputStream servletInputStream) {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(servletInputStream, Charset.forName("UTF-8")));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            log.error("異常 e:", e);
        } finally {
            if (servletInputStream != null) {
                try {
                    servletInputStream.close();
                } catch (IOException e) {
                    log.error("servletInputStream 關(guān)閉異常 e:", e);
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("reader 關(guān)閉異常 e:", e);
                }
            }
        }
        final String param = XssUtil.filterBody(sb.toString());
        log.info("getInputStream -> 過(guò)濾前參數(shù):{},過(guò)濾后參數(shù):{}", sb, param);
        return param;
    }
}
  • 重寫HttpServletRequestWrapper類用于過(guò)濾改變請(qǐng)求參數(shù)值
/**
 * 參數(shù)校驗(yàn)工具類
 *
 * @author: zrh
 * @date: 2021-11-17
 */
@Slf4j
public final class XssUtil {

    private XssUtil () {
    }

    /**
     * 網(wǎng)上找的XSS匹配正則表達(dá)式
     */
    private final static Pattern[] PATTERNS = new Pattern[]{
            // Script fragments
            Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
            // src='...'
            Pattern.compile("src[\r\n]*=[\r\n]*\'(.*?)\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            Pattern.compile("src[\r\n]*=[\r\n]*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            // lonely script tags
            Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
            Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            // eval(...)
            Pattern.compile("eval\((.*?)\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            // expression(...)
            Pattern.compile("expression\((.*?)\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            // javascript:...
            Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
            // vbscript:...
            Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
            // 空格英文單雙引號(hào)
            Pattern.compile("[\s'"]+", Pattern.CASE_INSENSITIVE),
            // onload(...)=...
            Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            // alert
            Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
            Pattern.compile("<", Pattern.MULTILINE | Pattern.DOTALL),
            Pattern.compile(">", Pattern.MULTILINE | Pattern.DOTALL),
            //Checks any html tags i.e. <script, <embed, <object etc.
            Pattern.compile("(<(script|iframe|embed|frame|frameset|object|img|applet|body|html|style|layer|link|ilayer|meta|bgsound))")
    };

    /**
     * 對(duì)請(qǐng)求對(duì)象參數(shù)進(jìn)行過(guò)濾校驗(yàn)
     *
     * @param params
     * @return
     */
    public static String filterBody (String params) {
        try {
            if (StringUtils.isBlank(params)) {
                return params;
            }
            final Map<String, Object> map = JSONObject.parseObject(params, Map.class);
            if (map.isEmpty()) {
                return params;
            }

            // 參數(shù)過(guò)濾
            final Iterator<Map.Entry<String, Object>> iterator = map.entrySet().stream().iterator();
            while (iterator.hasNext()) {
                final Map.Entry<String, Object> next = iterator.next();
                next.setValue(filterParam(next.getValue()));
            }
            return JSON.toJSONString(map);
        } catch (Exception e) {
            log.error("XSS過(guò)濾異常:", e);
        }
        return params;
    }

    /**
     * 對(duì)請(qǐng)求字符串參數(shù)進(jìn)行過(guò)濾校驗(yàn)
     *
     * @param param
     * @param <T>
     * @return
     */
    public static <T> Object filterParam (T param) {
        if (param instanceof String) {
            try {
                String value = String.valueOf(param);
                for (Pattern pattern : PATTERNS) {
                    value = pattern.matcher(value).replaceAll("");
                }
                return value;
            } catch (Exception e) {
                log.error("XSS參數(shù)過(guò)濾異常:", e);
            }
        }
        return param;
    }
}
  • XSS過(guò)濾參數(shù)的正則工具類
/**
 *
 * @Author: ZRH
 * @Date: 2021/11/17
 */
@RestController
public class XssTest {

    @PostMapping("/xss/test")
    public String test (@RequestBody JSONObject jsonObject) {
        System.out.println(jsonObject.toJSONString());
        return "OK";
    }

    @GetMapping("/xss/test")
    public String test (@RequestParam Integer data, @RequestParam String result) {
        System.out.println(data);
        return "OK";
    }
}

模擬請(qǐng)求響應(yīng)結(jié)果:
17:07:06.597 - [http-nio-8888-exec-1] - getHeaders -> header:content-type,過(guò)濾前參數(shù):application/json,過(guò)濾后參數(shù):application/json
17:07:06.598 - [http-nio-8888-exec-1] - getHeaders -> header:token,過(guò)濾前參數(shù):123,過(guò)濾后參數(shù):123
17:07:06.598 - [http-nio-8888-exec-1] - getHeaders -> header:a,過(guò)濾前參數(shù):123,過(guò)濾后參數(shù):123
17:07:06.598 - [http-nio-8888-exec-1] - getHeaders -> header:b,過(guò)濾前參數(shù):<script>alert("XSS");</script>,過(guò)濾后參數(shù):
17:07:06.599 - [http-nio-8888-exec-1] - getHeaders -> header:content-length,過(guò)濾前參數(shù):67,過(guò)濾后參數(shù):67
17:07:06.599 - [http-nio-8888-exec-1] - getHeaders -> header:host,過(guò)濾前參數(shù):localhost:8888,過(guò)濾后參數(shù):localhost:8888
17:07:06.599 - [http-nio-8888-exec-1] - getHeaders -> header:connection,過(guò)濾前參數(shù):Keep-Alive,過(guò)濾后參數(shù):Keep-Alive
17:07:06.599 - [http-nio-8888-exec-1] - getHeaders -> header:user-agent,過(guò)濾前參數(shù):Apache-HttpClient/4.5.12 (Java/11.0.8),過(guò)濾后參數(shù):Apache-HttpClient/4.5.12(Java/11.0.8)
17:07:06.599 - [http-nio-8888-exec-1] - getHeaders -> header:accept-encoding,過(guò)濾前參數(shù):gzip,deflate,過(guò)濾后參數(shù):gzip,deflate
17:07:06.648 - [http-nio-8888-exec-1] - getInputStream -> 過(guò)濾前參數(shù):{  "a": "1",  "b": 2,  "c": "<script>alert(\"XSS\");</script>"},過(guò)濾后參數(shù):{"a":"1","b":2,"c":""}
{"a":"1","b":2,"c":""}

最后

  • 除了可以使用過(guò)濾器以外,還可以使用攔截器進(jìn)行攔截校驗(yàn)。大致流程也差不多,先獲取參數(shù),然后進(jìn)行校驗(yàn),最后重新賦值。
  • 上述代碼例子只是簡(jiǎn)單粗化版,在實(shí)際項(xiàng)目中要根據(jù)需求進(jìn)行代碼調(diào)整和性能優(yōu)化后才可在線上使用。

到此這篇關(guān)于Java過(guò)濾XSS腳本攻擊的文章就介紹到這了,更多相關(guān)Java過(guò)濾XSS腳本攻擊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java遞歸運(yùn)行的機(jī)制:遞歸的微觀解讀圖文分析

    Java遞歸運(yùn)行的機(jī)制:遞歸的微觀解讀圖文分析

    這篇文章主要介紹了Java遞歸運(yùn)行的機(jī)制:遞歸的微觀解讀,結(jié)合圖文形式詳細(xì)分析了java遞歸運(yùn)行的原理、機(jī)制與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • MyBatis Plus 入門使用詳細(xì)教程

    MyBatis Plus 入門使用詳細(xì)教程

    這篇文章主要介紹了MyBatis Plus 入門使用詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot 集成 Memcached的方法示例

    SpringBoot 集成 Memcached的方法示例

    這篇文章主要介紹了SpringBoot 集成 Memcached的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • IDEA中的打包Build Artifacts圖文詳解

    IDEA中的打包Build Artifacts圖文詳解

    當(dāng)項(xiàng)目開(kāi)發(fā)完畢,需要對(duì)外發(fā)布時(shí),我們就會(huì)用到IDEABuild Artifacts功能,那么如果在idea中打包呢,這篇文章主要介紹了IDEA中的打包Build Artifacts詳解,需要的朋友可以參考下
    2024-03-03
  • Java阻塞隊(duì)列四組API介紹(小結(jié))

    Java阻塞隊(duì)列四組API介紹(小結(jié))

    這篇文章主要介紹了Java阻塞隊(duì)列四組API介紹,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 如何實(shí)現(xiàn)Java中一個(gè)簡(jiǎn)單的LinkedList

    如何實(shí)現(xiàn)Java中一個(gè)簡(jiǎn)單的LinkedList

    LinkedList與ArrayList都是List接口的具體實(shí)現(xiàn)類。下面將介紹如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的LinkedList,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 基于IDEA 的遠(yuǎn)程調(diào)試 Weblogic的操作過(guò)程

    基于IDEA 的遠(yuǎn)程調(diào)試 Weblogic的操作過(guò)程

    這篇文章主要介紹了基于IDEA 的遠(yuǎn)程調(diào)試 Weblogic的操作過(guò)程,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • java去除中文括號(hào)小括號(hào),或者英文括號(hào)的實(shí)例代碼

    java去除中文括號(hào)小括號(hào),或者英文括號(hào)的實(shí)例代碼

    這篇文章主要介紹了java去除中文括號(hào)小括號(hào),或者英文括號(hào)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Spring Boot實(shí)戰(zhàn)之模板引擎

    Spring Boot實(shí)戰(zhàn)之模板引擎

    這篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之模板引擎,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • SpringBoot集成EasyExcel的步驟

    SpringBoot集成EasyExcel的步驟

    EasyExcel是阿里巴巴開(kāi)源poi插件之一,主要解決了poi框架使用復(fù)雜,sax解析模式不容易操作,數(shù)據(jù)量大起來(lái)容易OOM,解決了POI并發(fā)造成的報(bào)錯(cuò)。主要解決方式:通過(guò)解壓文件的方式加載,一行一行的加載,并且拋棄樣式字體等不重要的數(shù)據(jù),降低內(nèi)存的占用。
    2021-06-06

最新評(píng)論