高能预警:Lombok相爱相杀的安全隐患

2024-08-22 00:18

本文主要是介绍高能预警:Lombok相爱相杀的安全隐患,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

不得不承认,Lombok 是一个很不错的 Java 库,它可以让你在少写代码的同时耍耍酷,简单的几个注解,就可以干掉一大片模板代码。但是,所有的源代码很多时候是用来阅读的,只有很少的时间是用来执行的 (你可以细品这句话)。

 

接下来,我将用几个大家耳熟能详的场景,重演我们是如何掉入 Lombok 的戏法陷阱。

 

# 爱的开始,恨的起源

 

面对 Lombok 提供的诸多 “神走位”,你并不会介意在 IDE 上新增一个插件。对于 IntelliJ IDEA 玩家而言,只需搜索 “Lombok Plugin” 便可找到这款神器并安装上它。爱上 Lombok 从安装 Lombok 插件开始,恨也从此萌芽。

 

没使用 Lombok 之前,我们的源代码看起来是这一的:

public class MyObject{    private Long id;    private String name;    private int age;    private int gender;
    public Long getId(){        return id;    }    public void setId(Long id){        this.id = id;    }    public String getName(){        return name;    }    public void setName(String name){        this.name = name;    }    public int getAge(){        return age;    }    public void setAge(int age){        this.age = age;    }    public int getGender(){        return gender;    }    public void setGender(int gender){        this.gender = gender;    }
    @Override    public boolean equals(Object o){        if(this == o){            return true;        }        if(o == null || getClass() != o.getClass()){            return false;        }        MyObject obj = (MyObject) o;        return age = obj.age &&            gender = obj.gender &&            Objects.equals(id,obj.id) &&            Objects.queals(name,obj.name);    }
    @Override    public int hashCode(){        return Objects.hash(id,name,age,gender);    }
    @Override    public String toString(){        return "MyObject{"+            "id="+id+            "name="+name+            "age="+age+            "gender="+gander+            "}";    }}

 

每个 JavaBean 都会充斥着如上述 getter,setter,equals,hashCode 和 toString 的模板代码,这看起来像一个偏胖的人(不得不承认 Java 是一个有缺陷的编程语言)。

 

当我们安装好 Lombok 插件后,IDE 便可以识别其酷炫的注解,使用 Lombok 的 @Getter 和 @Setter 注解后,代码会像下面这样看起来很苗条:

@Getter@Setterpublic class MyObject{    private Long id;    private String name;    private int age;    private int gender;
    @Override    public boolean equals(Object o){        if(this == o){            return true;        }        if(o == null || getClass() != o.getClass()){            return false;        }        MyObject obj = (MyObject) o;        return age = obj.age &&            gender = obj.gender &&            Objects.equals(id,obj.id) &&            Objects.queals(name,obj.name);    }
    @Override    public int hashCode(){        return Objects.hash(id,name,age,gender);    }
    @Override    public String toString(){        return "MyObject{"+            "id="+id+            "name="+name+            "age="+age+            "gender="+gander+            "}";    }}

 

现在的代码是否看起来爽多了?但这还不是最爽的时候。

 

既然其他方法都替换掉了,那把 toString 方法也一起拿掉吧。如你所愿,可以使用 @ToString 注解去掉对于的方法:

 
@Getter@Setter@EqualsAndHashCodepublic class MyObject{    private Long id;    private String name;    private int age;    private int gender;
    @Override    public String toString(){        return "MyObject{"+            "id="+id+            "name="+name+            "age="+age+            "gender="+gander+            "}";    }}

 

经过 Lombok 的戏法之后,相比一开始的代码,看起来是不是很酷炫,很苗条,很性感?你以为到此为止了?

 

远不止于此。你会发现类名上一大坨注解看起来好别扭,Lombok 提供了一个组合注解 @Data,可以替换掉类名头上那坨像翔一样的东西:

 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
@Datapublic class MyObject{    private Long id;    private String name;    private int age;    private int gender;}

 

现在,Lombok 是否让你的对象成为了你心目中完美的样子?魔鬼的 “身材”,酷炫精炼。Lombok 还有其他一些注解,如 @Slf4j,@NoArgsConstructor,@AllArgsConstructor 等等,介绍 Lombok 用法不是本文重点。

 

以上代码行数的变化过程,也许是无数程序员爱上 Lombok 的主要原因吧,这就像一个肥胖的人逐渐变成一个身材苗条的人。

 

同时也让你看到了一个现象:你以为程序员很懒吗?其他有些时候他们比你想象中的还要懒。在爽的同时,也为代码种下了祸根。

 

# 扭曲的审美,爱的隐患

 

扭曲的审美,导致了被审视的对象处于亚健康状态。使用 Lombok 插件之后,我们的代码也处于 “亚健康” 状态。还是回归一开始的那句话:所有的源代码很多时候是用来阅读的,只有很少的时间是用来执行的。

 

本质上讲,我们都追求减少程序中的样板代码以使其代码更精炼简洁,从而提高代码的可读性和可维护性。

 

但 Lombok 并没有达到我们所追求的这一愿景,它仅仅是利用 Java 语言在编译时的空档期,使用一种很取巧的方式,将我们所需要的方法注入(写入)到当前的类中,这种过程很像在 hack 我们的代码,只是一种看起来酷炫的把戏。

 

这种把戏并不智能和安全,反而会破坏 Java 代码现有的特性以及代码的可读性。

 

下面,结合我自己使用 Lombok 之后的感受,谈谈 Lombok 带来的几大痛点。

 

1. JDK 版本问题

 

当我想要将现有项目的 JDK 从 Java 8 升级到 Java 11 时,我发现 Lombok 不能正常工作了。

 

于是我不得不将所有的 Lombok 注解从项目源代码中清除,并使用 IDE 自带的功能生成 getter/setter,equals,hashCode,toString 以及构造器等方法,你也可以使用 Delombok 工具完成这一过程。但这终究会消耗你很多的时间。

 

2. 胁迫使用

 

当你的源代码中使用了 Lombok,恰好你的代码又被其他的人所使用,那么依赖你代码的人,也必须安装 Lombok 插件 (不管他们喜不喜欢),同时还要花费时间去了解 Lombok 注解的使用情况,如果不那么做,代码将无法正常运行。使用过 Lombok 之后,我发现这是一种很流氓的行为。

 

3. 可读性差

 

Lombok 隐藏了 JavaBean 封装的细节,如果你使用 @AllArgsConstructor 注解,它将提供一个巨型构造器,让外界有机会在初始化对象时修改类中所有的属性。

 

首先,这是极其不安全的,因为类中某系属性我们是不希望被修改的;另外,如果某个类中有几十个属性存在,就会有一个包含几十个参数的构造器被 Lombok 注入到类中,这是不理智的行为;

 

其次,构造器参数的顺序完全由 Lombok 所控制,我们并不能操控,只有当你需要调试时才发现有一个奇怪的 “小强” 在等着你;

 

最后,在运行代码之前,所有 JavaBean 中的方法你只能想象他们长什么样子,你并不能看见。

 

4. 代码耦合度增加

 

当你使用 Lombok 来编写某一个模块的代码后,其余依赖此模块的其他代码都需要引入 Lombok 依赖,同时还需要在 IDE 中安装 Lombok 的插件。

 

虽然 Lombok 的依赖包并不大,但就因为其中一个地方使用了 Lombok,其余所有的依赖方都要强制加入 Lombok 的 Jar 包,这是一种入侵式的耦合,如果再遇上 JDK 版本问题,这将是一场灾难。

 

5. 得不偿失

 

使用 Lombok,一时觉得很爽,但它却污染了你的代码,破坏了 Java 代码的完整性,可读性和安全性,同时还增加的团队的技术债务,这是一种弊大于利,得不偿失的操作。如果你确实想让自己的代码更加精炼,同时又兼顾可读性和编码效率,不妨使用主流的 Scala 或 Kotlin 这一基于 JVM 的语言。

 

# 总 结

 

Lombok 本身是一个优秀的 Java 代码库,它采用了一种取巧的语法糖,简化了 Java 的编码,为 Java 代码的精简提供了一种方式,但在使用此代码库时,需要了解到 Lombok 并非一个标准的 Java 库。

 

使用 Lombok,会增加团队的技术债务,降低代码的可读性,增大代码的耦合度和调式难度。

 

虽然在一定程度上 Lombok 减少了样板代码的书写,但也带来了一些未知的风险。

 

如果你正在参与一个团队项目(或大型项目), 考虑到后续的升级与扩展,是否使用 Lombok,请与你的团队多沟通和三思。

这篇关于高能预警:Lombok相爱相杀的安全隐患的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094695

相关文章

深入了解 Lombok 的 `@SneakyThrows` 注解

在 Java 编程中,异常处理是一个重要而繁琐的任务,特别是当你需要处理受检异常(checked exceptions)时。Lombok 的 @SneakyThrows 注解为简化异常处理提供了一种便捷的方法。本文将详细探讨 @SneakyThrows 注解的工作原理、优缺点以及使用示例。 什么是 @SneakyThrows 注解? @SneakyThrows 是 Lombok 提供的一

【spring】Lombok注解:data和AllArgsConstructor

data和AllArgsConstructor Lombok 库的注解:data和AllArgsConstructor @Data@AllArgsConstructorprivate static class Key {private String tId;private String tType

IDEA 安装lombok插件不兼容的问题及解决方法

解决:IDEA 安装lombok插件不兼容问题,plugin xxxx is incompatible 一、去官网下载最新的2024版本 地址传送通道: lombok插件官网地址https://plugins.jetbrains.com/plugin/6317-lombok/versions/stable  二、修改参数的配置 在压缩包路径 lombok-plugin -> li

癌症发生的时候,有什么状态预警吗?

周五啦,又是划水的一天 本来开开心心的刷知乎热搜,刷到这一条。 本来生活不易,要是来个这,那还不得急死,但是这也是可以防范的。 为了更多的了解这方面的知识,还特地开通的知乎盐选的盐选会员∠( ᐛ 」∠)_ 个人觉得有必要让各位小伙伴知道的也会在博客贴出 珍爱生命! [scode type="red"]纯属推广知识,望各位小伙伴悉知。[/scode] 早期发现,早点治疗! 最后附上一张:十

【一嗨租车-注册安全分析报告-滑动验证加载不正常导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如何? 请看具体分析 一、

Lombok和MapStruct整合

说明: Lombok和MapStruct都是用来简化Java代码的组件,它可以通过AnnotationProcessor在编译时自动生成代码,简化了我们日常开发。 原理: 自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。 lombok本质上就是这样的

【国铁采购平台-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如

Lombok 工具中@Data注解生成hashCode()可能导致StackOverflowError情况

看了大学一位同学博客,写了内容大致就是对于一个类中出现了该类的集合,通过Lombok的@Data注解生成class文件,当创建两个这个类的对象并且互相之间引用的时候,就出现了StackOverflowError异常,即栈溢出,或者叫超出栈深度.        在Java虚拟机内存区域分为两种一种是线程共享区域,另一种是线程私有区域,而虚拟机栈就处在线程私有区域中,虚拟机栈描述的是Jav

测试人员如何管理项目与风险预警

在平时工作过程中,你有没有因项目延时,需求频繁变更,开发提测质量不高,以及漏测的情况下,背了不少锅的情况呢? 作为测试人员,我们应该如何发挥积极主动性,进行项目管理,有效的控制项目流程? 在项目流程推过过程中,如果出现有风险,如何进行高效及时的风险预警? 一、测试管理都做什么工作? 1、需求评审与关键节点确认 积极组织需求评审,并对项目的各个核心节点进行确认 2、相应交付物之检测