如何检测Maven依赖中的隐藏遥测?获取依赖关联包类方法(IntelliJ/Gradle)
检测Maven/Gradle依赖中的隐藏遥测及敏感依赖排查方案
一、检测隐藏回传/遥测的最佳方法
- 静态代码扫描与敏感调用排查
直接在IntelliJ中针对外部依赖做全局搜索,重点查找java.net.HttpURLConnection、java.net.http.HttpClient、okhttp3.OkHttpClient等网络请求类的调用,以及java.io.FileOutputStream、java.nio.file.Files等文件操作类的调用。搜索范围选择「External Libraries」,快速定位可疑依赖的代码逻辑。 - 依赖树审计
用Gradle命令./gradlew dependencies生成完整依赖树,排查名称包含telemetry、analytics、tracking等关键词的依赖(包括子依赖)。也可以用./gradlew dependencyInsight --dependency <可疑包名>精准查看该依赖的引入路径。 - 运行时监控拦截
借助IntelliJ的Debug模式,在java.net.HttpURLConnection.openConnection()或java.io.File.createNewFile()等敏感方法上设置断点,触发程序运行后查看调用栈,确认是哪个依赖发起的操作。也可以用Java代理工具(如Byte Buddy)编写简单的拦截器,实时打印所有网络/文件操作的调用方信息。 - 权限强制管控
利用Java的SecurityManager或JPMS模块化机制限制依赖权限:- 配置
java.policy文件,禁止特定依赖的网络连接、文件读写权限,一旦触发违规操作会直接抛出SecurityException; - 在项目中添加
module-info.java,明确声明依赖所需的模块(如requires java.net.http;),未声明的敏感模块调用会在编译/运行阶段暴露。
- 配置
二、获取依赖(含子依赖)的所有包/类列表
Gradle 方式
- 自定义任务导出
在build.gradle中添加以下任务,运行后会遍历所有runtime依赖的JAR包,输出包含的所有类和包:
执行命令:task listAllDependencyClasses { doLast { configurations.runtimeClasspath.each { jarFile -> if (jarFile.name.endsWith('.jar')) { println "\n=== 依赖包: ${jarFile.name} ===" new java.util.jar.JarFile(jarFile).entries().each { entry -> if (!entry.isDirectory() && entry.name.endsWith('.class')) { def fullClassName = entry.name.replace('/', '.').replace('.class', '') def packageName = fullClassName.substring(0, fullClassName.lastIndexOf('.')) println "- 类: $fullClassName (包: $packageName)" } } } } } }./gradlew listAllDependencyClasses即可得到完整列表。 - 依赖树导出
用./gradlew dependencies --configuration runtimeClasspath > dependency-tree.txt将依赖树导出到文件,结合文本工具筛选子依赖的包名。
IntelliJ 方式
- 在「Project」视图中展开「External Libraries」,直接点击每个依赖的JAR包,查看内部的包结构和类文件;
- 使用「Structure」工具(快捷键
Alt+7),选中某个依赖JAR后,可快速浏览其所有类和成员。
三、重点排查java.net.*、java.io.*等敏感包的依赖
- IntelliJ 精准搜索
使用「Find in Path」(快捷键Ctrl+Shift+F),搜索内容输入import java.net.*或import java.io.*,搜索范围选择「External Libraries」,可直接定位到依赖中引入敏感包的类。 - Gradle 过滤任务
扩展上面的listAllDependencyClasses任务,添加过滤逻辑,只输出包含java.net或java.io的类:task listSensitiveClasses { doLast { configurations.runtimeClasspath.each { jarFile -> if (jarFile.name.endsWith('.jar')) { new java.util.jar.JarFile(jarFile).entries().each { entry -> if (!entry.isDirectory() && entry.name.endsWith('.class')) { def fullClassName = entry.name.replace('/', '.').replace('.class', '') if (fullClassName.startsWith('java.net.') || fullClassName.startsWith('java.io.')) { println "- 敏感类: $fullClassName (来自依赖: ${jarFile.name})" } } } } } } } - 依赖分析工具
启用IntelliJ的「Dependency Analyzer」(在「Project Structure」→「Modules」→「Dependencies」中可访问),查看每个依赖的依赖关系,确认是否间接引入了网络/IO相关的底层库。
内容的提问来源于stack exchange,提问作者Markus Kramer
相关产品推荐
相关产品推荐

