首页 > 编程语言 >Hello-Java-Sec 项目 (代码审计)

Hello-Java-Sec 项目 (代码审计)

时间:2024-10-10 14:10:55浏览次数:1  
标签:return String url public content Sec Java 序列化 Hello

一、项目背景:

Hello-Java-Sec项目为 Github中 一个面向安全开发的 Java漏洞代码审计靶场。

靶场地址:https://github.com/j3ers3/Hello-Java-Sec 本地使用idea部署即可

image

二、代码审计:

通过阅读代码可知,代码采用 @RequestMapping 注解的方式来处理 HTTP不同方法的请求,故采用 全局搜索@RequestMapping注解来查看路由的方式,进行进一步的审计。

image

(一)、SQL注入:

1、JDBC注入:

(1)、语句拼接,过滤不当导致SQL注入:

image

未对用户传入的 id 值进行判断过滤,导致产生SQL注入

image

可采用黑名单的方式,对敏感字符进行过滤操作:

public static boolean checkSql(String content) {
    String[] black_list = {"'", ";", "--", "+", ",", "%", "=", ">", "*", "(", ")", "and", "or", "exec", "insert", "select", "delete", "update", "count", "drop", "chr", "mid", "master", "truncate", "char", "declare"};
    for (String s : black_list) {
        if (content.toLowerCase().contains(s)) {
            return true;
        }
    }
    return false;
}

(2)、预编译使用不当导致SQL注入:

image

虽然使用了 prepareStatement()方法进行预编译,但是并没有使用 ? 进行占位,导致代码本质上还是 sql语句的拼接,导致产生SQL注入。

可采用 ? 进行占位处理,修复代码如下:

public String safe1(String id) {
    String sql = "select * from users where id = ?";
    PreparedStatement st = conn.prepareStatement(sql);
    st.setString(1, id);
    ResultSet rs = st.executeQuery();
}

靶场还给出了另外两种可以防御SQL注入的代码,如下所示:
(1) ESAPI安全框架:

// ESAPI 是一个免费、开源的、网页应用程序安全控件库,它使程序员能够更容易写出更低风险的程序
// 官网:https://owasp.org/www-project-enterprise-security-api/


public String safe3(String id) {
    Codec<Character> oracleCodec = new OracleCodec();

    Statement stmt = conn.createStatement();
    String sql = "select * from users where id = '" + ESAPI.encoder().encodeForSQL(oracleCodec, id) + "'";

    ResultSet rs = stmt.executeQuery(sql);
}

其中 encodeForSQL方法对输入的特殊字符进行了转义处理,例如单引号 ' 会被转义为 ''。

(2) 强制数据类型:

// 如果参数类型为boolean,byte,short,int,long,float,double等,sql语句无法拼接字符串,因此不存在注入

public Map<String, Object> safe4(Integer id) {
    String sql = "select * from users where id = " + id;
    return jdbctemplate.queryForMap(sql);
}

若进行字符串拼接,会进行报错处理,提示我们需要输入一个 Integer类型,而不是String类型的值。
image

2、MyBatis框架中的SQL注入:

MyBatis框架:MyBatis 自动处理 JDBC 的繁琐工作,如建立连接、准备和执行 SQL 语句、处理结果集等。它简化了 JDBC 编程,提供了强大的动态 SQL 功能,并且支持多种数据库。

(1) 搜索框注入 ('%#{q}%' 和 '%${q}%' 使用不当):

image

用户输入的任意值被复制给参数q,并使用search()方法进行操作,跟进search()方法:
image

search()方法中采用 '%${q}%' 的方式进行SQL查询语句拼接,导致SQL注入的产生,因为由于使用 ${}语法,传入的参数值会直接插入到SQL查询语句中,未经过任何转义或处理,若其中包括敏感字符、恶意代码,就会导致SQL注入攻击。
image

解决此问题,可以采用 '%#{q}%' ,#{}语法会将传入的参数值作为预编译参数进行处理,对敏感字符进行转义,安全代码如下:

// 安全代码,采用concat
@Select("select * from users where user like concat('%',#{q},'%')")
List<User> search(String q);

也可以采取强制类型的方案进行修复,使其只能传入指定类型的值:

@Select("select * from users where id = ${id}")
List<User> queryById2(@Param("id") Integer id);

(2) order by注入:

order by注入产生的本质依然是 ${}语法的不当使用。

观察下图代码,调用了 userMapper接口中的 order by 方法,并传入参数 field 和 sort:
image

userMapper 是一个接口,通常是由 MyBatis 生成的,这个接口定义了与数据库进行交互的方法。userMapper接口中 order by 方法的实现通常在 MyBatis 的XML映射文件或注解中定义。

order by方法在 XML映射文件中的定义如下所示:
image

定义采用 ${} 语法,若 field = id; drop table users --,sort = asc,语句拼接就会组成恶意代码:

select * from users order by id;drop table users-- asc

同理,order by 方法在注解中的定义若使用了 ${}语法,同样也会产生SQL注入问题:
image

解决此问题,可以采用排序映射的方法:

<select id="orderBySafe" resultType="com.best.hello.entity.User">
    select * from users
    <choose>
        <when test="field == 'id'">
            order by id desc
        </when>
        <when test="field == 'user'">
            order by user desc
        </when>
        <otherwise>
            order by id desc
        </otherwise>
    </choose>
</select>

用户可输入的值只有 id 和 user两个,有效防止了SQL注入。

(二) 文件上传漏洞:

全局搜索 @RequestMapping("/UPLOAD") 寻找文件上传接口:
image

发现代码中未对上传文件后缀名做任何校验,导致用户可以上传任意文件,如 .php、.jsp等。

可以使用白名单对上传文件的后缀名进行规范:

// 对上传文件后缀名做白名单处理

public String singleFileUploadSafe(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {
    try {
        byte[] bytes = file.getBytes();
        String fileName = file.getOriginalFilename();
        Path dir = Paths.get(UPLOADED_FOLDER);
        Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());

        // 获取文件后缀名
        String Suffix = fileName.substring(fileName.lastIndexOf("."));
        // 后缀名白名单
        String[] SuffixSafe = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
        boolean flag = false;
        // 校验后缀名
        for (String s : SuffixSafe) {
            if (Suffix.toLowerCase().equals(s)) {
                flag = true;
                break;
            }
        }

        if (!flag) {
            return "只允许上传图片,[.jpg, .png, .jpeg, .gif, .bmp, .ico]";
        }

(三) 目录穿越 -> 任意文件读取/下载:

未对用户可控的 filename 的参数值进行过滤,导致使用 ../ 进行目录穿越,从而造成任意文件下载/读取:
image

目录穿越读取日志信息:
image

可以通过过滤 /字符 和 ..等非法字符的方式防止目录穿越:

// 过滤..和/ ,可以防止遍历操作

public String safe(String filename) {
    if (!Security.checkTraversal(filename)) {  //对非法字符进行过滤
        String filePath = System.getProperty("user.dir") + "/logs/" + filename;
        return "安全路径:" + filePath;
    } else {
        return "检测到非法遍历";
    }
}

public static boolean checkTraversal(String content) {
    return content.contains("..") || content.contains("/");
}

(四) XSS:

(1) 反射型XSS:

未对用户输入的内容进行字符转义与过滤处理,导致解析恶意JS代码,造成XSS攻击
image

防御手段有很多种:
1、使用 Spring自带的方法对特殊字符进行转义:

// 采用Spring自带的方法会对特殊字符全转义

import org.springframework.web.util.HtmlUtils;

@GetMapping("/safe1")
public static String safe1(String content) {
    return HtmlUtils.htmlEscape(content);
}

2、采用OWASP Java Encoder会对特殊字符全转义:

import org.owasp.encoder.Encode;
public static String safe5(String content){
    return Encode.forHtml(content);
}

3、使用ESAPI.encoder().encodeForHTML(content)方法对content中的特殊字符进行转义:

// ESAPI 是一个免费、开源的、网页应用程序安全控件库,它使程序员能够更容易写出更低风险的程序
// 官网:https://owasp.org/www-project-enterprise-security-api/

import org.owasp.esapi.ESAPI;
public static String safe4(String content){
    return ESAPI.encoder().encodeForHTML(content);
}

对敏感字符进行转义后如下图所示:
image

4、富文本场景下使用黑白名单的方式,严格规范标签的使用,防止解析恶意JS代码:

// 场景:针对富文本的处理方式,需保留部分标签

import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;

public static String safe3(String content) {
    Safelist whitelist = (new Safelist())
           .addTags("p", "hr", "div", "img", "span", "textarea")  // 设置允许的标签
           .addAttributes("a", "href", "title")          // 设置标签允许的属性, 避免如nmouseover属性
           .addProtocols("img", "src", "http", "https")  // img的src属性只允许http和https开头
           .addProtocols("a", "href", "http", "https");
    return Jsoup.clean(content, whitelist);
}

(2) 存储型XSS:

论坛、社区等评论区等场景,未对用户输入的内容 content参数进行转义过滤,直接add添加,导致攻击者输入的恶意JS代码被页面解析,产生XSS漏洞。
image

修复本质上也是对输入的敏感字符进行转义处理:
1、使用org.springframework.web.util.HtmlUtils工具类中的 HtmlUtils.htmlEscape()方法对字符进行转义:

public String safeStore(HttpServletRequest request) {
    String content = request.getParameter("content");
    String safe_content = HtmlUtils.htmlEscape(content);
    xssMapper.add(safe_content);
    return "success";
}

2、前端输出转义:

$('#xssTableSafe tbody').append('<tr><td>' + item.id + '</td><td>' + $('<div/>').text(item.content).html() + '</td></tr>');

image

(五) SSRF漏洞:

(1) 未作任何限制的 SSRF漏洞:

未对用户可控的url参数做任何形式的限制和过滤,导致攻击者可以直接请求内网,以及利用file等伪协议读取敏感信息:
image

使用 file协议访问任意文件:
image

访问内网:
image

通常会采用白名单的方式进行修复,禁止攻击者使用除 HTTP/HTTPS协议之外的其他协议,并且禁止其访问内网:

public String URLConnection3(String url) {
    if (!Security.isHttp(url)) {
        return "不允许非http/https协议!!!";
    } else if (!Security.isWhite(url)) {
        return "非可信域名!";
    } else {
        return HttpClientUtil.URLConnection(url);
    }
}

但是这种白名单防御可以通过302跳转等方式进行绕过,所以更好的防御代码如下所示:

public String HTTPURLConnection(String url) {
    // 校验 url 是否以 http 或 https 开头
    if (!Security.isHttp(url)) {
        log.error("[HTTPURLConnection] 非法的 url 协议:" + url);
        return "不允许非http/https协议!!!";
    }

    // 解析 url 为 IP 地址
    String ip = Security.urltoIp(url);
    log.info("[HTTPURLConnection] SSRF解析IP:" + ip);

    // 校验 IP 是否为内网地址
    if (Security.isIntranet(ip)) {
        log.error("[HTTPURLConnection] 不允许访问内网:" + ip);
        return "不允许访问内网!!!";
    }

    try {
        return HttpClientUtils.HTTPURLConnection(url);
    } catch (Exception e) {
        log.error("[HTTPURLConnection] 访问失败:" + e.getMessage());
        return "访问失败,请稍后再试!!!";
    }
}

// 1. 判断是否为http协议
public static boolean isHttp(String url) {
    return url.startsWith("http://") || url.startsWith("https://");
}

// 2. 解析IP地址
public static String urltoIp(String url) {
    try {
        URI uri = new URI(url);
        String host = uri.getHost().toLowerCase();
        InetAddress ip = Inet4Address.getByName(host);
        return ip.getHostAddress();
    } catch (Exception e) {
        return "127.0.0.1";
    }
}

// 3. 判断是否为内网IP
public static boolean isIntranet(String url) {
    Pattern reg = Pattern.compile("^(127\\.0\\.0\\.1)|(localhost)|^(10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|^(172\\.((1[6-9])|(2\\d)|(3[01]))\\.\\d{1,3}\\.\\d{1,3})|^(192\\.168\\.\\d{1,3}\\.\\d{1,3})$");
    Matcher match = reg.matcher(url);
    Boolean a = match.find();
    return a;
}

// 4. 不允许302跳转
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setInstanceFollowRedirects(false); // 不允许重定向或者对重定向后的地址做二次判断
conn.connect();
}

(六)RCE(远程代码执行):

(1) ProcessBuilder方式导致RCE

对攻击者输入未作过滤,攻击者使用管道符进行RCE:
image

正常输入:filepath = "/path/to/file"
执行命令:sh -c "ls -l /path/to/file"

管道符拼接后:filepath = "/path/to/file; whoami"
执行命令:sh -c "ls -l /path/to/file; whoami"

可以采用黑名单的方式进行修复,将管道符全部过滤:

public static boolean checkOs(String content) {
    String[] black_list = {"|", ",", "&", "&&", ";", "||"};
    for (String s : black_list) {
        if (content.contains(s)) {
            return true;
        }
    }
    return false;
}

(2) Runtime.getRuntime().exec(); 的不当使用导致RCE:

Runtime.getRuntime().exec(cmd)中,会执行cmd参数中的命令,若cmd可控且未进行过滤处理,回导致RCE。
image

cmd /c start calc 命令弹出计算器:
image

可以通过设置白名单的方式,严格过滤用户输入的命令,防止RCE:

// 使用白名单替换黑名单。黑名单需要不断更新,而白名单只需要指定允许执行的命令,更容易维护。

public static String safe(String cmd) {
    // 定义命令白名单
    Set<String> commands = new HashSet<\>();
    commands.add("ls");
    commands.add("pwd");

    // 检查用户提供的命令是否在白名单中
    String command = cmd.split("\\s+")[0];
    if (!commands.contains(command)) {
        return "命令不在白名单中";
    }
    ...
}

用户只允许输入并执行白名单中指定的命令,禁止恶意命令。

(3) ProcessImpl类中的start()方法造成RCE:

ProcessImpl 是更为底层的实现,Runtime和ProcessBuilder执行命令实际上也是调用了ProcessImpl这个类,ProcessImpl 类是一个抽象类不能直接调用,但可以通过反射来间接调用ProcessImpl来达到执行命令的目的。
image

但代码中未对 cmd参数值进行过滤操作,导致可能会执行恶意代码造成RCE。修复方式同上,采用白名单对用户输入的值进行严格限制。

(4) 脚本引擎(ScriptEngine)代码注入:

image

load()函数用户从指定的URL处加载并执行 Javascript 脚本,若 某URL-> http://hacker.com/xxx.js 中的JS代码为恶意代码,被 eval()函数执行后,造成RCE。

可以采用白名单的方式进行修复,先验证用户输入的 URL 是否在白名单中,若在,则加载JS代码,若不在,抛出异常:

private static final Pattern ALLOWED_URL_PATTERN = Pattern.compile("^https?://(localhost|127\\.0\\.0\\.1|example\\.com)/.*$");

public void jsEngine(String url) throws Exception {
        // 验证 URL 是否可信
        if (!ALLOWED_URL_PATTERN.matcher(url).matches()) {
            throw new IllegalArgumentException("Invalid URL: " + url);
        }

(5) Groovy使用不当造成RCE:

image

使用 GroovyShell中的 evaluate()方法进行命令执行,本质上依然是未对 cmd参数进行过滤操作,同理采用白名单的方式进行修复即可。

(七) Java反序列化漏洞:

(1) 重写ObjectInputStream对象的readObject()方法不当造成反序列化漏洞:

许多类在实现 Serializable 接口时,会对 readObject()方法进行重写来执行自定义的反序列化逻辑。比如攻击者构造了一个类名为 MaliciousClass,在这个类中,攻击者对 readObject()方法进行了重写,重写的 readObject方法中会执行恶意代码。当 MaliciousClass类被反序列化时,类中的 readObject()方法被调用,导致恶意代码的执行。

import java.io.*;

public class MaliciousClass implements Serializable {
    private static final long serialVersionUID = 1L;

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        // 恶意代码
        Runtime.getRuntime().exec("rm -rf /");
    }
}

image

反序列化目标的值用户可控,导致可以对任意类进行反序列化操作,攻击者构造一个恶意类进行反序列化,就可以实现RCE。

可以使用限定用户只能对指定类进行反序列化的方式来预防:

// 使用Apache Commons IO的ValidatingObjectInputStream,accept方法来实现反序列化类白/黑名单控制

public String safe(String base64) {
    try {
        base64 = base64.replace(" ", "+");
        byte[] bytes = Base64.getDecoder().decode(base64);

        ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
        ValidatingObjectInputStream ois = new ValidatingObjectInputStream(stream);

        // 只允许反序列化Student class
        ois.accept(Student.class);
        ois.readObject();

        return "ValidatingObjectInputStream";
     } catch (Exception e) {
        return e.toString();
}

通过黑/白名单的方式,只允许反序列化 Student 等合法类。

(2) yaml.load()使用不当造成反序列化

org.yaml.snakeyaml.Yaml 为 SnakeYAML的主类,用于解析和生成YAML格式的文档。类SnakeYAML中的load方法会将 YAML文档中的数据反序列化为 Java对象,若 YAML 文档中的内容包含恶意构造的数据,则会造成反序列化漏洞。

image

未对 yaml.load()函数的 content参数进行严格的过滤,导致产生反序列化漏洞。

image

可以使用 SafeConstructor来进行防御。SafeConstructor 是 SnakeYAML 提供的一个安全的构造器类,它限制了可以反序列化的类。默认情况下,SafeConstructor 只允许反序列化基本类型(如字符串、数字、布尔值)、集合类型(如列表和映射)以及其他一些安全的类。这样可以防止攻击者通过恶意构造的 YAML 数据来执行任意代码。

// SafeConstructor 是 SnakeYaml 提供的一个安全的构造器。它可以用来构造安全的对象,避免反序列化漏洞的发生。

public void safe(String content) {
    Yaml y = new Yaml(new SafeConstructor());
    y.load(content);
    log.info("[safe] SnakeYaml反序列化: " + content);
}

SafeConstructor只允许反序列化一些基本类型的类,和一些自定义添加的安全类。添加自定义的安全类,比如Student类,代码如下所示:

public class CustomSafeConstructor extends SafeConstructor {

    public CustomSafeConstructor() {
        this.yamlConstructors.put(new Tag("!student"), new ConstructStudent());
    }

    private class ConstructStudent extends AbstractConstruct {
        @Override
        public Object construct(Node node) {
            Map<String, Object> values = (Map<String, Object>) constructMapping(node);
            String name = (String) values.get("name");
            int age = (int) values.get("age");
            return new Student(name, age);
        }
    }
}

public class Student {
  xxxxxxxxx  //get、set方法;name、age参数等
}

(3) XMLDecoder解析XML文件造成反序列化漏洞:

image

XMLDecoder中的readObject方法在反序列化对象时,会执行XML文件中的恶意代码,导致产生反序列化漏洞,造成RCE。

包含恶意代码的XML文件可以如下所示,调用ProcessBuilder类中的 start()方法来执行恶意代码:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_231" class="java.beans.XMLDecoder">
  <object class="java.lang.ProcessBuilder">
    <array class="java.lang.String" length="3">
      <void index="0">
        <string>rm</string>
      </void>
      <void index="1">
        <string>-rf</string>
      </void>
      <void index="2">
        <string>/</string>
      </void>
    </array>
    <void method="start"/>  //调用 ProcessBuilder类中的 start()方法,实现命令执行
  </object>
</java>

(八) XXE漏洞:

漏洞触发点就在XML解析时,因此重点审计XML解析器是否设置了相关的安全属性。

(1) XMLReader (org.xml.sax.XMLReader)

image

攻击者可以通过构造一个包含恶意外部实体的XML文档,达到任意文件读取、内网端口探测等恶意目的。

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
        <!ENTITY xxe SYSTEM "http://dnslog.cn">
       ]>
    <root>&xxe;</root>

修复XXE漏洞,可以规定在使用XML解析器时,禁止使用外部实体:

public String XMLReader(@RequestBody String content) {
    try {
        XMLReader xmlReader = XMLReaderFactory.createXMLReader();
        // 修复:禁用外部实体
        xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        xmlReader.parse(new InputSource(new StringReader(content)));
        return "XMLReader XXE";
    } catch (Exception e) {
        return e.toString();
    }
}

(2) SAXReader (org.dom4j.io.SAXReader):

SAXReader是Apache dom4j库中的一个类,用于解析XML数据。
image

未禁用外部实体解析导致产生XXE。

(3) SAXBuilder (org.jdom.input.SAXBuilder):

SAXBuilder 是 JDOM 库中的一个类,用于解析 XML 数据。
image

未禁用外部实体解析导致产生XXE。

(4) DocumentBuilder (DocumentBuilder):

DocumentBuilder 是 Java 的 javax.xml.parsers 包中的一个类,用于解析 XML 文档并将其转换为 DOM 树。
image

未禁用外部实体解析导致产生XXE。

(5) Unmarshaller (javax.xml.bind.Unmarshaller):

Unmarshaller 是 Java Architecture for XML Binding (JAXB) 的核心类之一,用于将 XML 数据转换为 Java 对象。
image

未禁用外部实体解析导致产生XXE。

(九) 越权漏洞:

(1) 水平越权

水平越权的产生通常是由于后端未进行权限校验导致的。
image

可以采用使用 session、token等方式进行防御,简易的防御代码如下所示:

// 判断当前session与要查询的用户是否一致
public String safe(String name, HttpSession session) {
    if (session.getAttribute("LoginUser").equals(name)) {
        return userMapper.queryByUser(name);
    }
}

image

(4) 垂直越权:

垂直越权的产生是 admin 和 user的权限未作区分,导致普通用户可以向上垂直越权使用管理员的功能:
image

同理进行权限校验即可:

// 只允许admin用户可以访问管理页面
public String safe(HttpSession session) {
    if (session.getAttribute("LoginUser").equals("admin")) {
        return "admin";
    } else {
        return "commons/403";
    }
}

(十) 未授权访问:

拦截器中没有对未授权路径进行拦截导致未授权访问:
image

拦截未授权路径即可。

(十一) JNDI注入:

image

攻击者可以通过构造特定的 content 参数,利用 JNDI 查找功能来加载远程恶意代码,从而在服务器上执行任意代码。这通常通过 RMI 或 LDAP 协议实现。

可采用白名单的方式进行修复,限制 lookup方法只能查找预定义的、安全的资源:

public String safe2(String content) {
    List<String> whiteList = Arrays.asList("java:comp/env/jdbc/mydb", "java:comp/env/mail/mymail");
    if (whiteList.contains(content)) {
        try {
            Context ctx = new InitialContext();
             ctx.lookup(content);
         } catch (Exception e) {
             log.warn("JNDI错误消息");
         }
        return HtmlUtils.htmlEscape(content);  //返回经过转义的 content,也有效防止了XSS攻击
    } else {
        return "JNDI 白名单拦截";
    }
}

(十三) CSRF漏洞:

CSRF漏洞的产生大多是因为未校验 csrf_token 和 Referer头导致。
image

image

若对 csrf_token 和 Referer头进行校验,就可以很好的防御CSRF漏洞:
(1) 校验csrf_token:

 String token = request.getParameter("csrfToken");
 String sessionToken = (String) session.getAttribute("csrfToken");

 // 校验CSRF Token
 if (!token.equals(sessionToken)) {
     result.put("success", false);
     result.put("message", "token is not valid");
     return result;
 }

(2) 校验 Referer头:

 String token = request.getParameter("csrfToken");
 String sessionToken = (String) session.getAttribute("csrfToken");

 // 校验CSRF Token
 if (!token.equals(sessionToken)) {
     result.put("success", false);
     result.put("message", "token is not valid");
     return result;
 }

(十四) URL重定向漏洞:

利用URL重定向中的被信任域名来钓鱼,关键参数:url、redirectURL、target等。
image

采用白名单进行防御,只允许跳转到白名单中设置的安全地址:

public static boolean isWhite(String url) {
    List<String> url_list = new ArrayList<String>();
    url_list.add("baidu.com");
    url_list.add("www.baidu.com");
    url_list.add("oa.baidu.com");

    URI uri = null;
    try {
        uri = new URI(url);
    } catch (URISyntaxException e) {
        System.out.print(e);
    }
    String host = uri.getHost().toLowerCase();
    System.out.println(host);

    return url_list.contains(host);
 }

(十五) DOS(拒绝服务)漏洞:

漏洞代码:

public String vul(String content) {

    boolean match = Pattern.matches("(a|aa)+", content);
    return String.format("正则匹配:%s,正则表达式拒绝服务攻击", match);
}

安全代码:

public String safe(String content) {
    boolean match = com.google.re2j.Pattern.matches("(a|aa)+", content);
    return String.format("正则匹配:%s,安全正则表达式", match);
}

若 content的值很长,很复杂,漏洞代码会出现DOS漏洞。

原因:

漏洞代码中进行正则匹配使用的是 Java内置的正则表达式引擎->java.util.regex.Pattern。在处理某些特定的输入时,可能会导致指数级的时间复杂度,从而引发 ReDoS 攻击。例如,对于正则表达式 (a|aa)+,输入 aaaaaaaaaaaaaaaaaaaaaaa! 会导致引擎花费大量时间进行匹配。

而安全代码中则使用了 RE2 正则表达式引擎->com.google.re2j.Pattern。设计上避免了回溯,因此在处理复杂正则表达式时具有线性的时间复杂度->O(n),不会引发 ReDoS 攻击。

(十六) Swagger未授权访问:

修复很简单->限制访问环境即可:

@Configuration
@EnableSwagger2
// 设置swagger只能在dev和test环境可访问
@Profile({"dev", "test"})
public class Swagger2Config {

}

标签:return,String,url,public,content,Sec,Java,序列化,Hello
From: https://www.cnblogs.com/kgty/p/18452324

相关文章

  • 【Ubuntu】在Ubuntu上配置Java环境
    【Ubuntu】在Ubuntu上配置Java环境壹、前言Java是运用得非常广泛的编程语言,在使用Linux时难免会碰到需要用到JDK的情况,故本文介绍如何在Ubuntu上配置Java21环境。贰、下载Java的下载渠道很多,有甲骨文公司的“官方”JDK,也有各大厂商基于OpenJDK开发的版本,但是各个版本间的差异......
  • Java 函数式编程(1 万字)
    此笔记来自于B站黑马程序员goodJava历史版本及其优势函数式编程,StreamAPI一.函数伊始函数、函数对象函数对象行为参数法延迟执行a-lambdab-方法引用复习小测Math::random()->Math.random()Math::sqrt(doublenumber)->Math.sqrt(number)Stude......
  • Java设计方式(3 万字)
    Java设计模式来源于尚硅谷韩顺平这个课非常不错,还有配套的资料!!!Java设计模式的七大原则单一职责原则基本介绍对类来说的,即一个类应该只负责一项职责如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度......
  • Spring Security(常见过滤器介绍)
    SpringSecurity是一个基于Spring框架的安全性解决方案,为Java应用程序提供了一套全面的安全解决方案。一、概述SpringSecurity是Spring采用AOP(面向切面编程)思想,基于servlet过滤器实现的安全框架。它致力于保护基于Spring的应用程序,并成为了这类应用的事实上的安全标准。S......
  • JAVA基础之九-泛型(通用类型)
    总体而言,泛型(通用类型)是一个好东西,它是一个工程上起到好处的东西,对于性能、安全等并没有什么帮助。在java工程上,泛型属于必须掌握的,理由如下:1.各种源码中基本上都有泛型,无论是java基础源码还是Spring或者阿帕奇的。不掌握这个,你读不懂。你没有方法饶过它2.有了泛型,某种程度上......
  • java解压rar,解压zip
    解压zippackagecom.xcg.webapp.common;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.nio.charset.Charset;importjava.util.zip.ZipFile;publicclassZipUtil{/***解压zi......
  • 深入探讨JavaScript中的精度问题:原理与解决方案
    深入探讨JavaScript中的精度问题:原理与解决方案在日常的JavaScript开发中,我们经常会遇到一些令人困惑的数值计算问题,特别是涉及到小数点运算时。例如,为什么0.1+0.2的结果不是预期的0.3,而是0.30000000000000004?本文将详细介绍JavaScript中出现精度问题的原因,深入解析十进......
  • JavaScript Number研究03_实例方法_toExponential_toFixed_toPrecision_toString_valu
    JavaScriptNumber研究03:实例方法——toExponential、toFixed、toPrecision、toString、valueOf、toLocaleString在JavaScript中,Number对象不仅包含了许多有用的静态属性,还提供了一系列实例方法,帮助我们在不同场景下处理和转换数值。这些方法包括:toExponential()toFixed()......
  • PTA 作业三 继承与多态 JAVA 6-1 从抽象类shape类扩展出一个圆形类Circle 面向对象程
    6-1从抽象类shape类扩展出一个圆形类Circle分数25作者 张德慧单位 西安邮电大学请从下列的抽象类shape类扩展出一个圆形类Circle,这个类圆形的半径radius作为私有成员,类中应包含初始化半径的构造方法。publicabstractclassshape{//抽象类publicabstractdoubleg......
  • PTA 作业三 继承与多态 JAVA 面向对象程序设计7-1 周长计算器-1分数 30作者 Ma 单位
    7-1周长计算器-1分数30作者 Ma单位 山东科技大学1、定义一个接口Shape用于表示图形,其包含一个doublelength()的方法用于求周长。2、定义三角形类Triangle、长方形类Rectangle、圆形类Circle分别实现接口Shape3、定义测试类ShapeTest并使用Shape接口定义变......