FindBugs-IDEA插件的使用

一、 前言

FindBugs是一款Java静态代码分析工具,与其他静态分析工具(如Checkstyle和PMD)不同,FindBugs不注重样式或者格式,它专注于寻找真正的缺陷或者潜在的性能问题,它可以帮助java工程师提高代码质量以及排除隐含的缺陷。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。Eclipse中有插件可以帮助查找代码中隐藏的bug,IDEA中也有这款插件。
在FindBugs中,可以安装一个针对代码安全性进行检测的组件,叫做Find-sec-bugs。此组件包含了130种(2019-03-27版本)针对安全性的检测规则,对于我们源码的安全审计工作帮助很大。
这篇文章,我们就介绍下基于IDEA平台的FindBugs插件的安装及使用方法,以及Find-sec-bugs组件的安装方法。

二、安装

打开IDEA,点击左上角的File—Settings进入设置界面,然后点击Plugins进入插件窗口,直接联网进行搜索findbugs,点击Install安装。详情见下图的操作截图。
在这里插入图片描述
在这里插入图片描述

安装完之后,重启IDEA,会发现左下角会出现FindBugs-IDEA的图标。
在这里插入图片描述

接下来我们进行安装findbugs安全规则组件:Find-sec-bugs
在Find-sec-bus插件的官方下载地址:https://find-sec-bugs.github.io/进行下载最新的版本文件。
在这里插入图片描述
打开IDEA进行插件的安装。
依然是进入:File—Settings

点击FindBugs-IDEA,进入FindBugs的设置窗口。点击Plugins下面的加号进行组件的导入,然后选择4.Install plugin from disk。在路径中选择之前下载的插件文件,然后点击OK。详细操作步骤见下面截图。
在这里插入图片描述在这里插入图片描述

这样FindBugs插件和其安全性规则的Find-sec-bugs插件都已经安装完成。

三、 FindBugs的使用说明

1. FindBugs的功能按键

不同的编号的意义为:
在这里插入图片描述
1、分析选中的 Java 文件
2、分析选中的类
3、分析选中的包
4、分析选中的模块 (点击时会询问是否同时分析 test 包中的类)
5、分析整个项目 (点击时会询问是否同时分析 test 包中的类)
6、分析自定义的类(点击进入会有详细的自定义选项)
7、分析被修改的类 (搭配 SVN,Git 使用)
8、分析 changelist 中的类 (搭配 SVN,Git 使用)
9、停止分析
10、清除并且关掉FindBugs工具窗口
11、FindBugs-IDEA帮助
12、根据 BUG 类型分组
13、根据类分组
14、根据包分组
15、根据 BUG 严重级别分组
16、autoscroll to source(自动滚动到可能的bug的源位置,就是如果你选择了此项设置,在点击bug列表时候,在上面的源代码位置,就会自动展现出此BUG发生的源代码。不适用于导入的XML报告,因为没有源代码工程。)
17、展示当前选择的Bug的源代码(此项单纯指的是在FindBugs-IDEA窗口下展示源代码。)
18、搜索功能(可以搜索Bug名称,不能搜索源码)
19、展开所有Bug列表
20、折叠所有Bug列表
21、插件设置
22、导出Bug扫描的报告(可以选择HTML格式和XML格式,HTML的好处是自己观看更直观,XML的好处是可以利用下面23号按钮的功能进行导入查看。)
23、导入Bug扫描的报告(只支持XML格式进行导入)。

2. FindBugs的设置

可以通过两个地方进行FindBugs的设置。第一种是上述的21号按钮。第二种是点击File—Settings,选择FindBugs—IDEA进入设置界面。

需要注意的是:FindBugs的设置,只针对当前的工程。

下面介绍下设置页面的功能描述:

在这里插入图片描述

1) 常规设置General:

1、Compile affected files before analyze 在分析之前进行编译
2.、Analyze affect files affter comlplie 在变动的文件编译之后自动进行分析
3.、Analyze affect files after auto make 在自动Make之后自动分析变动的文件
4.、Run analyze in background 在后台分析,不显示进度条窗口
5.、Active toolwindow on run 在分析过程中展示按钮(工具窗口)

在这里插入图片描述

2) 报告设置Report

1、Analysis effort 分析的深入程度(分析级别)
Minimal—最低级别
Default—默认级别
Maximal—最高级别

2、Minimum rank错误级别
数字越小越严重,配置数字越小筛选的范围也越小。例如选择20-Of Concern既显示最多的BUG数。反之,选择1-Scariest既只显示符合规则的部分BUG。

3、Minimum confidence 报告中显示Bug的最低等级
Hign—高等级(选择此项只显示高等级BUG)
Medium—中等级
Low –低等级(选择此项显示所有BUG)

4、Bad pratice
编程的坏习惯
主要是命名问题,比如类名最好以大写开头,字符串不要使用等号不等号进行比较,可能会有异常最好用try-catch包裹的代码,方法有返回值但被忽略等等,这些如果不想改可以直接忽略.
HE:类中equals()与hashCode()没有同时定义,或者使用了错误的对象的hashCode()或equals()。
SQL:Statement 的execute方法调用了非常量的字符串;或Prepared Statement是由一个非常量的字符串产生。
DE: 方法终止或不处理异常,一般情况下,异常应该被处理或报告,或被方法抛出。

5、Malicious code vulnerability
恶意代码漏洞
听起来很吓人呀,主要是一些属性直接使用public让别的类来获取,建议改为private并为其提供get/set方法. 还有一些public的静态字段,可能会被别的包获取之类的. 这些也需要根据项目具体情况来,个人意见,在有的不重要类,有时直接公开使用属性,可能更为便捷.如果你认为这些不需要修改,完全可以忽略.

6、correctness
代码的正确性 这一项应该算是最重要的了
主要是没有对变量进行不为空判定,在特殊情况可能发生空指针异常。下面列举几个:
NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否null;null值产生并被引用;null值产生并在方法的异常路径被引用;传给方法一个声明为@NonNull的null参数;方法的返回值声明为@NonNull实际是null。
Nm: 类定义了hashcode()方法,但实际上并未覆盖父类Object的hashCode();类定义了tostring()方法,但实际上并未覆盖父类Object的toString();很明显的方法和构造器混淆;方法名容易混淆。
SQL:方法尝试访问一个Prepared Statement的0索引;方法尝试访问一个ResultSet的0索引。
UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。

7、performance
性能
主要是一些无用的代码,比如声明了没有用到的属性等等
NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否null;null值产生并被引用;null值产生并在方法的异常路径被引用;传给方法一个声明为@NonNull的null参数;方法的返回值声明为@NonNull实际是null。
Nm: 类定义了hashcode()方法,但实际上并未覆盖父类Object的hashCode();类定义了tostring()方法,但实际上并未覆盖父类Object的toString();很明显的方法和构造器混淆;方法名容易混淆。
SQL:方法尝试访问一个Prepared Statement的0索引;方法尝试访问一个ResultSet的0索引。
UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。

8、security—我们进行源码安全审计主要是勾选此项
安全性。后续会针对此处有详细的介绍。

9、Dodgy code
糟糕的代码
比如一个double/float被强制转换成int/long可能会导致精度损失,一些接近零的浮点数会被直接截断,事实上我们应该保留. 这里顺便提一点,这两天看了《app研发录》,在规范代码,尽量规避错误这方面我也有了一些收获. 在类型转换的时候,我们应该为类型转换提供一个安全的转换方法,因为我们永远不会知道,我们的app在用户手里会发生什么,所以我们要尽可能的去减少这种发生错误的可能.比如使用switch的时候没有提供default。多余的空检查,就是不可能为空的值,增加了不为空判断,这是没有必要的。属于代码冗余不安全的类型转换等等。 这项太多了,就不一一列举了。

10、Experimental
实验 (参考)
https://blog.csdn.net/jdsjlzx/article/details/21472253/
1.LG: Potential lost logger changes due to weak reference in OpenJDK (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE)
OpenJDK的引入了一种潜在的不兼容问题,特别是,java.util.logging.Logger的行为改变时。它现在使用内部弱引用,而不是强引用。–logger配置改变,它就是丢失对logger的引用,这本是一个合理的变化,但不幸的是一些代码对旧的行为有依赖关系。这意味着,当进行垃圾收集时对logger配置将会丢失。例如:
public static void initLogging() throws Exception {
Logger logger = Logger.getLogger(“edu.umd.cs”);
logger.addHandler(new FileHandler()); // call to change logger configuration
logger.setUseParentHandlers(false); // another call to change logger configuration
}
该方法结束时logger的引用就丢失了,如果你刚刚结束调用initLogging方法后进行垃圾回收,logger的配置将会丢失(因为只有保持记录器弱引用)。
public static void main(String[] args) throws Exception {
initLogging(); // adds a file handler to the logger
System.gc(); // logger configuration lost
Logger.getLogger(“edu.umd.cs”).info(“Some message”); // this isn’t logged to the file as expected
}
2.OBL: Method may fail to clean up stream or resource (OBL_UNSATISFIED_OBLIGATION)
这种方法可能无法清除(关闭,处置)一个流,数据库对象,或其他资源需要一个明确的清理行动。
一般来说,如果一个方法打开一个流或其他资源,该方法应该使用try / finally块来确保在方法返回之前流或资源已经被清除了。这种错误模式基本上和OS_OPEN_STREAM和ODR_OPEN_DATABASE_RESOURCE错误模式相同,但是是在不同在静态分析技术。我们正为这个错误模式的效用收集反馈意见。

11、Multithreaded Correctness
多线程问题
DL_SYNCHRONIZATION_ON_BOOLEAN
Synchronization on Boolean could lead to deadlock 该代码同步一个封装的原始常量,例如一个Boolean类型
private static Boolean inited = Boolean.FALSE; … synchronized(inited) { if (!inited) { init(); inited = Boolean.TRUE; } } …
由于通常只存在两个布尔对象,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁
DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE
Synchronization on boxed primitive could lead to deadlock
该代码同步一个封装的原始常量,例如一个Integer类型。
private static Integer count = 0; … synchronized(count) { count++; } …
由于Integer对象可以共享和保存,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁
DL_SYNCHRONIZATION_ON_SHARED_CONSTANT
Synchronization on interned String could lead to deadlock
同步String类型的常量时,由于它被JVM中多个其他的对象所共有,这样在其他代码中会引起死锁。

12、Internationalization
国际化
当对字符串使用upper或lowercase方法,如果是国际的字符串,可能会不恰当的转换。

3) 过滤器设置Filter

此功能作用是:过滤器将针对一组条件的错误实例进行匹配。通过定义过滤器,您可以选择错误实例进行特殊处理; 例如,将其排除或包含在报告中。
使用方法:将相应的规则作成一份 XML文档,然后,在配置页面中导入这份配置文档即可。
如何制作相应的过滤器XML文件,可以参考官方文档:
http://findbugs.sourceforge.net/manual/filter.html

4) 扫描规则配置Detector

在这里插入图片描述
此处是选择你想使用的检测规则。
Provider:根据规则提供者分类,我们这里分成两类(Find security Bugs和FindBugs)
Speed:根据扫描速度进行分类
Bug Category:根据规则类别进行分类:例如Security安全类。
鼠标点击规则名称,右面的Description会显示相应的描述。

5) Bug注解Annotate

默认设置即可,主要是图标和注解的显示,意义不大。

6) 导入设置文件Share

在这里插入图片描述

此功能支持Sonar和FindBugs的配置文件导入。导入之后,系统会直接识别导入的设置,不会根据当前界面的设置进行执行。设置文件只能是XML格式的。我们在进行源码的安全性扫描的时候,设置一般是固定的,可以导出一份设置文件进行留存,在其他项目的时候直接导入即可使用。
导出的按钮为上图的红色圆圈处的Export。导入的地方有两个入口,都在上图中标识了红色方框。

3. FindBugs的执行

在这里插入图片描述

编号的相应功能如下:
1.分析选中文件
2.分析包下面的所有文件
3.分析整个Module下的所有文件
4.分析整个Project下的所有文件
5.分析自定义选择的一些文件(点击按钮之后就能看到如何自定义)
6.分析所有修改的文件
7.分析changelist中的文件

分析完之后就会出现结果面板

在这里插入图片描述

点击对应的item在右边会定位到具体的代码

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值