《IntelliJ IDEA 插件开发》第七节:通过Inspection机制,对静态代码安全审查

简介: 一、前言二、需求目的三、案例开发1. 工程结构2. 伪随机数检测3. FastJson检测4. 提醒模板5. 检测配置四、测试验证五、总结六、系列推荐

目录


  • 一、前言
  • 二、需求目的
  • 三、案例开发
  • 1. 工程结构
  • 2. 伪随机数检测
  • 3. FastJson检测
  • 4. 提醒模板
  • 5. 检测配置
  • 四、测试验证
  • 五、总结
  • 六、系列推荐


一、前言

真能闹,怕喇喇蛄,还不种稻子了?

喇喇蛄,是东北的一种害虫,经常在种水稻的季节,在池埂子上盗洞,导致稻田里的水悄悄的流没了,影响稻苗发育。

后来发现原来写代码,也能碰见“蝲蝲蛄”,无论你写的是什么功能、哪种技术、作何目的,蝲蝲蛄总能给盗几个洞出来。“你这已经有其他的某某了你怎么还造轮子”、“你这方案不行程序员不要浪费时间”、“也没看出来你这有啥优势和价值呀怎么给业务赋能”,这种话听上去“贼”有道理,吹的叮当的,但让他去做又能搞的稀的囊的。

所以,远离蝲蝲蛄,做你想做的、搞你想搞的、学你想学的,知识是不断沉淀的积累、方案是积累后的创造。

二、需求目的

怎么办,都有标准的研发规范,但还是没法控制住到具体的每个研发下,给写出什么代码了。

有时候标准只是文档,看和执行的这个过程中就会一定的转行失效性,你可能会想加手段;评审、扣钱、罚绩效、检讨等等,但这样可能还只是增加过程成本,最终效果也不会太好。不太可能一个写代码还得配一个保姆,所以就像 p3c、pmd-idea,这样的插件出来了,帮助程序员把代码写好,治理掉一些不合标准的问题代码。

那么,你好奇这个事是怎么干的吗,怎么你就在 IDEA 写代码,它就能给你检测出来,告诉你有问题,并提醒你修改以及有些还可以一键帮助你修改呢?那如果你想再增加点你们公司个性的要求的时候,怎么扩展呢?本章节我们就使用 IDEA 插件开发能力,把这个事办喽

三、案例开发

1. 工程结构

guide-idea-plugin-pmd
├── .gradle
└── src
    ├── main
    │   └── java
    │    └── cn.bugstack.guide.idea.plugin 
    │        ├── rule
    │        │   ├── FastJsonAutoType.java
    │        │   ├── HardcodedIp.java    
    │        │   └── ReplacePseudorandomGenerator.java         
    │        └── utils   
    │            └── InspectionBundle.java    
    ├── resources
    │   ├── inspectionDescriptions
    │   │   ├── FastJsonAutoType.html
    │   │   ├── HardcodedIp.html  
    │   │   └── ReplacePseudorandomGenerator.html   
    │   └── META-INF
    │       └── plugin.xml 
    ├── build.gradle  
    └── gradle.properties

源码获取:#公众号:bugstack虫洞栈 回复:idea 即可下载全部 IDEA 插件开发源码

在此 IDEA 插件工程中,主要分为3块区域:

  • rule:规则配置区域,以继承 IDEA 原生 Inspection 检查类,扩展自身需要扫描的代码片段,进行警告、注释、修复。
  • inspectionDescriptions:是对应的警告注释,编写到 html 中,最终展示到 IDEA 下对应的问题代码片段上。
  • plugin.xml:中需要配置 localInspection 也就是配置你自定义的代码检测实现类。

2. 伪随机数检测

目的:把代码中的 new Random 不安全伪随机数警告并提供修复,处理为 new SecureRandom

RandomRule

image.gif2.jpg

PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
typeElement.replace(factory.createTypeElementFromText("SecureRandom", null));
PsiNewExpression secureNewExp = (PsiNewExpression) factory.createExpressionFromText("new SecureRandom()", null);
newExp.replace(secureNewExp);
  • 通过继承 AbstractBaseJavaLocalInspectionTool Override buildVisitor 方法,扩展检测代码。当你写了这段方法后,IDEA 会把一行行的代码都通过这个方法传进来
  • visitNewExpression 方法中扩展自身的检测处理,遇到了哪种代码片段,要提供什么样的提醒以及提醒的级别,最后是提供一个 Fix 修复能力,这个修复能力就在替换这段代码片段,通过还可以操作引入新包的动作 import xxx

3. FastJson检测

目的com.alibaba:fastjson 在开启 AutoTypeSupport 时,存在反序列化风险。如果程序中有 ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 代码直接提醒删除处理。

public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    return new JavaElementVisitor() {
        @Override
        public void visitMethodCallExpression(PsiMethodCallExpression expression) {
            if (hasFullQualifiedName(expression, "com.alibaba.fastjson.parser.ParserConfig", "setAutoTypeSupport")) {
                PsiExpression[] args = expression.getArgumentList().getExpressions();
                if (args.length == 1 &&
                        args[0] instanceof PsiLiteralExpression &&
                        Boolean.TRUE.equals(((PsiLiteralExpression) args[0]).getValue())
                ) {
                    holder.registerProblem(
                            expression,
                            "FastJson unserialization risk",
                            ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
                            new DeleteElementQuickFix(expression, "!Fix: remove setAutoTypeSupport")
                    );
                }
            }
        }
    };
}
  • 整个对代码检测的操作基本都是类似的,这个无非也是检测出代码库,并进行删除的提醒处理 DeleteElementQuickFix

4. 提醒模板

<html>
<body>
<b>小傅哥-提醒:</b> 不安全的伪随机数生成器 <br>
<br>
<p>java.util.Random 依赖一个可被预测的伪随机数生成器。</p>
<br>
<p style="font-size: 10px;color: #629460;">最佳实践:</p>
<p style="font-size: 10px;">使用java.security.SecureRandom</p>
</body>
</html>
  • 提醒模板需要编写 html 格式的内容,这个内容会被展示到错误代码的详情里。后面我们做测试的可以查看

5. 检测配置

<extensions defaultExtensionNs="com.intellij">
    <localInspection
            language="JAVA"       groupPath="Java"
            groupName="X-PMD"   enabledByDefault="true"   level="ERROR"
            bundle="InspectionBundle"     key="replace.pseudorandom.generator.name"
            implementationClass="cn.bugstack.guide.idea.plugin.rule.RandomRule"
    />
    <localInspection
            language="JAVA"       groupPath="Java"
            groupName="X-PMD"   enabledByDefault="true"   level="ERROR"
            bundle="InspectionBundle"     key="fastjson.auto.type.name"
            implementationClass="cn.bugstack.guide.idea.plugin.rule.FastJsonRule"
    />
    <localInspection
            language="JAVA"      groupPath="Java"
            groupName="X-PMD"  enabledByDefault="true"     level="WARNING"
            bundle="InspectionBundle"     key="hardcoded.ip.name"
            implementationClass="cn.bugstack.guide.idea.plugin.rule.IPRule"
    />
</extensions>
  • 在 plugin.xml 中配置我们自己开发好的代码静态检测对象,这样你的检测类就生效了。

四、测试验证

启动插件

image.gif3.jpg

  • 如果你下载代码后,没有 Plugin 可以自己配置一下,在 Tasks 中配置 :runIde

错误提醒

4.jpg

错误详情

5.jpg

  • 当你点击 Fix,那么接下来就可以进行自动替换代码并修复了,就是把 Random random = new Random() 替换为 SecureRandom random = new SecureRandom();
  • 其他2个也可以在获取代码后进行测试验证,一个是IP,另外一个是使用 ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 的错误提醒。

五、总结

  • 本章节我们学习了如何使用 IDEA 原生 Inspection 检查机制,扩展我们自己需要添加的代码检测逻辑,以及使用 LocalQuickFix 的实现类,做代码的替换和引入响应包的操作。
  • 另外对于代码检测,还有一个更加标准的工具叫 PMD 它是一款采用 BSD 协议的代码检查工具,你可以扩展实现为自己的标准和规范以及完善个性的提醒和修复操作。
  • 像 p3c 就是一款静态代码检测工具,用的人也非常多,不过它的插件开发不是基于 Java 实现的,代码开发上也并没有一些注释。所以非常建议阅读 pmd-idea,这款代码写的非常好,抽象充足、结构清晰、内容完整:https://github.com/ybroeker/pmd-idea
目录
相关文章
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
95 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
3月前
|
搜索推荐 Java 数据库连接
Java|在 IDEA 里自动生成 MyBatis 模板代码
基于 MyBatis 开发的项目,新增数据库表以后,总是需要编写对应的 Entity、Mapper 和 Service 等等 Class 的代码,这些都是重复的工作,我们可以想一些办法来自动生成这些代码。
41 6
|
6月前
|
IDE Oracle Java
day4:JDK、IntelliJ IDEA的安装和环境变量配置
【7月更文挑战第4天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
241 0
|
3月前
|
Java 应用服务中间件 Maven
【终极解决方案】IDEA maven 项目修改代码不生效。
【终极解决方案】IDEA maven 项目修改代码不生效。
519 1
|
3月前
|
Java Linux 开发工具
IDEA中git提交前如何关闭code analysis以及开启格式化代码
【10月更文挑战第12天】本文介绍了在 IntelliJ IDEA 中关闭代码分析和开启代码格式化的步骤。关闭代码分析可通过取消默认启用检查或针对特定规则进行调整实现,同时可通过设置 VCS 静默模式在提交时跳过检查。开启代码格式化则需在 `Settings` 中配置 `Code Style` 规则,并通过创建 Git 钩子实现提交前自动格式化。
829 3
|
4月前
|
Linux Windows
IDEA如何查看每一行代码的提交记录(人员,时间)
【9月更文挑战第24天】在IntelliJ IDEA中,可通过安装GitToolBox插件并利用其功能来便捷地查看每行代码的提交记录,包括提交者、时间和提交信息。具体操作为:首先安装GitToolBox插件,然后在代码编辑区域将鼠标悬停于目标代码行以查看简要信息,或使用快捷键打开“Version Control”窗口查看详细提交历史。
2552 2
|
5月前
|
Java 数据库连接 Spring
如何在IDEA中自定义模板、快速生成完整的代码?
这篇文章介绍了如何在IntelliJ IDEA中使用easycode插件自定义代码生成模板,以快速生成Spring Boot、MyBatis等项目中常见的Controller、Service、Dao、Mapper等组件的代码。
如何在IDEA中自定义模板、快速生成完整的代码?
|
5月前
|
XML 数据格式
IDEA 行注释设置,使其不从顶格开始,让其处于代码前开始
这篇文章提供了IntelliJ IDEA中如何设置行注释不从顶格开始,而是紧接在代码前面的方法,通过访问Settings中的Code Style选项进行调整,以改善代码注释的视觉效果。
|
5月前
|
开发工具 git
成功解决 IDEA 2020 版本 代码报错不提示的几种方案
这篇文章提供了几种解决IntelliJ IDEA 2020版本中代码报错不提示问题的方案,包括通过修改文件夹权限、暂存本地更改后进行git pull,以及在git pull后应用暂存的更改并提交代码到远程仓库的方法。
|
5月前
|
安全 开发工具 git
coding上创建项目、创建代码仓库、将IDEA中的代码提交到coding上的代码仓库、Git的下载、IDEA上配置git
这篇文章是关于如何在IDEA中配置Git、在Coding.net上创建项目和代码仓库,并将IDEA中的代码提交到远程代码仓库的详细教程,涵盖了Git安装、IDEA配置、项目创建、代码提交等步骤。
coding上创建项目、创建代码仓库、将IDEA中的代码提交到coding上的代码仓库、Git的下载、IDEA上配置git