Java 富文本XSS攻击防御,基于Jsoup的白名单过滤

springboot过滤器demo仓库 : https://gitee.com/withwindluo/springboot-richtext-xss-demo

1. jsoup依赖

  <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
  <dependency>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
      <version>1.12.1</version>
  </dependency>

2. 白名单json配置 xsswhiteList.json

{
    "addTags": [
        "p",
        "strong",
        "em",
        "u",
        "s",
        "blockquote",
        "pre",
        "h1",
        "h2",
        "h3",
        "h4",
        "h5",
        "h6",
        "br",
        "ol",
        "li",
        "ul",
        "sub",
        "sup",
        "span",
        "iframe",
        "a",
        "img"
    ],
    "addAttributes": [
        {
            "tag": ":all",
            "attributes": [
                "class",
                "id",
                "src",
                "style"
            ]
        },
        {
            "tag": "pre",
            "attributes": [
                "spellcheck"
            ]
        },
        {
            "tag": "iframe",
            "attributes": [
                "frameborder",
                "allowfullscreen",
                "src"
            ]
        },
        {
            "tag": "a",
            "attributes": [
                "rel",
                "target"
            ]
        },
        {
            "tag": "img",
            "attributes": [
                "align",
                "alt",
                "height",
                "src",
                "title",
                "width"
            ]
        }
    ],
    "addProtocols": [
        {
            "tag": "xx",
            "attribute": "src",
            "protocols": [
                "src",
                "http",
                "https",
                "data"
            ]
        }
    ]
}

3. 工具类

package com.esgov.csfw.commonUtils;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Objects;


/**
 * XSS工具
 *
 * @author withwindluo
 * @since 2021/12/9 18:52
 */
public class XSSUtil {

    private static final ClassPathResource jsoupWhiteListPathRes = new ClassPathResource("/json/xssWhiteList.json");

    //添加默认base配置,因为本项目的富文本图片实现使用base64,暂不使用默认的baseImage配置
//    private static Whitelist whitelist = Whitelist.basicWithImages();
    private static Whitelist whitelist = Whitelist.basic();

    //再载入json自定义白名单
    static {
        InputStream whiteConfig = null;
        try {
            whiteConfig = jsoupWhiteListPathRes.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (whiteConfig == null) {
            throw new RuntimeException("读取jsoup xss 白名单文件失败");
        } else {
            try {
                JSONObject whiteListJson = JSON.parseObject(whiteConfig, JSONObject.class);

                //添加标签 addTags
                JSONArray addTagsJsonArr = whiteListJson.getJSONArray("addTags");
                String[] addTagsArr = addTagsJsonArr.toArray(new String[0]);
                whitelist.addTags(addTagsArr);


                //添加属性 addAttributes
                JSONArray addAttrJsonArr = whiteListJson.getJSONArray("addAttributes");
                Iterator<Object> iter = addAttrJsonArr.iterator();
                while (iter.hasNext()) {
                    JSONObject attrJsonObj = (JSONObject) iter.next();
                    String tag = attrJsonObj.getString("tag");
                    JSONArray attrJsonArr = attrJsonObj.getJSONArray("attributes");
                    String[] attrArr = attrJsonArr.toArray(new String[0]);
                    whitelist.addAttributes(tag, attrArr);
                }


                //添加 addProtocols
                JSONArray addProtoJsonArr = whiteListJson.getJSONArray("addProtocols");
                iter = addProtoJsonArr.iterator();
                while (iter.hasNext()) {
                    JSONObject attrJsonObj = (JSONObject) iter.next();
                    String tag = attrJsonObj.getString("tag");
                    String attribute = attrJsonObj.getString("attribute");
                    JSONArray protoJsonArr = attrJsonObj.getJSONArray("protocols");
                    String[] protocolArr = protoJsonArr.toArray(new String[0]);
                    whitelist.addProtocols(tag, attribute, protocolArr);
                }


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private XSSUtil() {

    }

    /**
     * 使用jsoup设置标签放行白名单
     *
     * @param originStr
     * @return
     */
    public static String jsoupCleanRichText(String originStr) {

//        whitelist = (new Whitelist()
//                .addTags("a", "b", "div", "img", "p", "strong") // 设置允许的标签
//                .addAttributes("a", "href", "title", "...") // 设置标签允许的属性
//                .addAttributes(":all", "class", "id", "src") // 通配符,对所有标签配置允许的属性
//                .addProtocols("img", "src", "http", "https")); // 设置Protocol,这是代表img的src属性只允许http和https开头

        return Jsoup.clean(originStr, whitelist);
    }
}

4. 使用

public static void main(String[] args) {
     String s  = "<img src=1 οnerrοr=alert(1)>";
     System.out.println("origin:" + s );
     String result = XSSUtil.jsoupCleanRichText(s);
     System.out.println(result);
     System.out.println("filt: " + result);
 }

在这里插入图片描述

参考文章:

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值