通过Inspection机制,对静态代码安全审查

[[442105]]

一、前言

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

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

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

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

二、需求目的

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

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

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

三、案例开发

1. 工程结构

  1. guide-idea-plugin-pmd 
  2. ├── .gradle 
  3. └── src 
  4.     ├── main 
  5.     │   └── java 
  6.     │    └── cn.bugstack.guide.idea.plugin  
  7.     │        ├── rule 
  8.     │        │   ├── FastJsonAutoType.java 
  9.     │        │   ├── HardcodedIp.java     
  10.     │        │   └── ReplacePseudorandomGenerator.java          
  11.     │        └── utils    
  12.     │            └── InspectionBundle.java     
  13.     ├── resources 
  14.     │   ├── inspectionDescriptions 
  15.     │   │   ├── FastJsonAutoType.html 
  16.     │   │   ├── HardcodedIp.html   
  17.     │   │   └── ReplacePseudorandomGenerator.html    
  18.     │   └── META-INF 
  19.     │       └── plugin.xml  
  20.     ├── build.gradle   
  21.     └── gradle.properties 

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

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

2. 伪随机数检测

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

RandomRule

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

3. FastJson检测

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

  1. public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { 
  2.     return new JavaElementVisitor() { 
  3.         @Override 
  4.         public void visitMethodCallExpression(PsiMethodCallExpression expression) { 
  5.             if (hasFullQualifiedName(expression, "com.alibaba.fastjson.parser.ParserConfig""setAutoTypeSupport")) { 
  6.                 PsiExpression[] args = expression.getArgumentList().getExpressions(); 
  7.                 if (args.length == 1 && 
  8.                         args[0] instanceof PsiLiteralExpression && 
  9.                         Boolean.TRUE.equals(((PsiLiteralExpression) args[0]).getValue()) 
  10.                 ) { 
  11.                     holder.registerProblem( 
  12.                             expression, 
  13.                             "FastJson unserialization risk"
  14.                             ProblemHighlightType.GENERIC_ERROR_OR_WARNING, 
  15.                             new DeleteElementQuickFix(expression, "!Fix: remove setAutoTypeSupport"
  16.                     ); 
  17.                 } 
  18.             } 
  19.         } 
  20.     }; 

整个对代码检测的操作基本都是类似的,这个无非也是检测出代码库,并进行删除的提醒处理 DeleteElementQuickFix

4. 提醒模板

  1. <html> 
  2. <body> 
  3. <b>小傅哥-提醒:</b> 不安全的伪随机数生成器 <br> 
  4. <br> 
  5. <p>java.util.Random 依赖一个可被预测的伪随机数生成器。</p> 
  6. <br> 
  7. <p style="font-size: 10px;color: #629460;">最佳实践:</p> 
  8. <p style="font-size: 10px;">使用java.security.SecureRandom</p> 
  9. </body> 
  10. </html> 

 

 

 

提醒模板需要编写 html 格式的内容,这个内容会被展示到错误代码的详情里。后面我们做测试的可以查看

5. 检测配置

  1. <extensions defaultExtensionNs="com.intellij"
  2.     <localInspection 
  3.             language="JAVA"       groupPath="Java" 
  4.             groupName="X-PMD"   enabledByDefault="true"   level="ERROR" 
  5.             bundle="InspectionBundle"     key="replace.pseudorandom.generator.name" 
  6.             implementationClass="cn.bugstack.guide.idea.plugin.rule.RandomRule" 
  7.     /> 
  8.      
  9.     <localInspection 
  10.             language="JAVA"       groupPath="Java" 
  11.             groupName="X-PMD"   enabledByDefault="true"   level="ERROR" 
  12.             bundle="InspectionBundle"     key="fastjson.auto.type.name" 
  13.             implementationClass="cn.bugstack.guide.idea.plugin.rule.FastJsonRule" 
  14.     /> 
  15.      
  16.     <localInspection 
  17.             language="JAVA"      groupPath="Java" 
  18.             groupName="X-PMD"  enabledByDefault="true"     level="WARNING" 
  19.             bundle="InspectionBundle"     key="hardcoded.ip.name" 
  20.             implementationClass="cn.bugstack.guide.idea.plugin.rule.IPRule" 
  21.     /> 
  22. </extensions> 

 

在 plugin.xml 中配置我们自己开发好的代码静态检测对象,这样你的检测类就生效了。

四、测试验证

启动插件

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

错误提醒

错误详情

当你点击 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

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/149710.html<

(0)
管理的头像管理
上一篇2025-03-12 18:03
下一篇 2025-03-12 18:05

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注