From jar-analyzer-plugin
Executes SQL-based security audits on jar-analyzer.db from JAR analysis, including method call searches, call chains, Spring components, string searches, and vulnerability detection.
npx claudepluginhub jar-analyzer/jar-analyzer-claude --plugin jar-analyzer-pluginThis skill uses the workspace's default tool permissions.
在 `build-db` skill 构建好 `jar-analyzer.db` 后,使用本 skill 对数据库进行各类安全分析查询。
Builds SQLite analysis database from Java JAR/WAR/Class files using jar-analyzer-engine. Captures classes, methods, calls, inheritance, strings, Spring components for security audits and call analysis.
Scans codebases for security vulnerabilities using CodeQL data flow and taint tracking analysis. Supports Python, JavaScript/TypeScript, Go, Java, C#, Ruby, Swift.
Detects SQL injection vulnerabilities by tracing user inputs through code to database queries, flagging unsafe patterns like concatenation and unparameterized ORMs. Scans frameworks including Django, Rails, Express, Go.
Share bugs, ideas, or general feedback.
在 build-db skill 构建好 jar-analyzer.db 后,使用本 skill 对数据库进行各类安全分析查询。
通过 SQL 查询 + 反编译验证的方式,实现方法调用搜索、调用链追踪、漏洞模式检测等功能。
build-db skill 构建了 jar-analyzer.db 数据库jar-analyzer.db 文件不要在本文件中重复描述数据库表结构。 请参考
<plugin_dir>/references/DATABASE.md获取完整的数据库 Schema、字段说明、表关联关系和常用查询模式。
任何方法节点必须通过 四元组 唯一标识:
(jar_id, class_name, method_name, method_desc)
禁止仅用方法名进行 join 或追链,因为方法重载很常见。
数据库中的类名使用 / 分隔(JVM 内部格式),而非 . 分隔:
com/example/controller/UserControllercom.example.controller.UserController使用 JVM 方法描述符格式:
(Ljava/lang/String;)V = void method(String)(Ljava/lang/String;I)Ljava/lang/String; = String method(String, int)()V = void method()优先使用 sqlite3 命令行工具(直接、高效):
# 单条查询
sqlite3 jar-analyzer.db "SELECT COUNT(*) FROM method_table;"
# 格式化输出(带表头、列对齐)
sqlite3 -header -column jar-analyzer.db "SELECT class_name, method_name FROM method_table LIMIT 10;"
# 多条查询
sqlite3 -header -column jar-analyzer.db <<'EOF'
SELECT 'JAR文件' AS type, COUNT(*) AS count FROM jar_table
UNION ALL
SELECT '类', COUNT(*) FROM class_table
UNION ALL
SELECT '方法', COUNT(*) FROM method_table;
EOF
# 输出为 CSV
sqlite3 -header -csv jar-analyzer.db "SELECT * FROM spring_method_table;" > routes.csv
如果 sqlite3 不可用,使用 Python 作为备选:
import sqlite3
conn = sqlite3.connect('jar-analyzer.db')
cursor = conn.execute("SQL_QUERY_HERE")
for row in cursor:
print(row)
conn.close()
将上述代码写入临时
.py文件执行,分析完成后删除临时文件。
SELECT 'JAR文件' AS type, COUNT(*) AS count FROM jar_table
UNION ALL
SELECT '类', COUNT(*) FROM class_table
UNION ALL
SELECT '方法', COUNT(*) FROM method_table
UNION ALL
SELECT '方法调用', COUNT(*) FROM method_call_table
UNION ALL
SELECT '字符串常量', COUNT(*) FROM string_table
UNION ALL
SELECT 'Spring Controller', COUNT(*) FROM spring_controller_table
UNION ALL
SELECT 'Spring 映射', COUNT(*) FROM spring_method_table
UNION ALL
SELECT 'Servlet/Filter', COUNT(*) FROM java_web_table;
-- 查找谁调用了某个特定类的方法(精确搜索)
SELECT DISTINCT
caller_class_name, caller_method_name, caller_method_desc
FROM method_call_table
WHERE callee_class_name = 'java/lang/Runtime'
AND callee_method_name = 'exec';
-- 模糊搜索
SELECT DISTINCT
caller_class_name, caller_method_name,
callee_class_name, callee_method_name
FROM method_call_table
WHERE callee_class_name LIKE '%ClassName%'
AND callee_method_name LIKE '%methodName%';
-- 精确搜索
SELECT class_name, method_name, method_desc, is_static, line_number
FROM method_table
WHERE method_name = 'execute';
-- 模糊搜索
SELECT class_name, method_name, method_desc, line_number
FROM method_table
WHERE method_name LIKE '%upload%'
OR method_name LIKE '%file%';
-- 使用 SQLite 递归 CTE 追踪调用链(推荐)
WITH RECURSIVE call_chain AS (
SELECT caller_class_name, caller_method_name, caller_method_desc,
callee_class_name, callee_method_name, callee_method_desc, 1 AS depth
FROM method_call_table
WHERE callee_class_name = 'java/lang/Runtime' AND callee_method_name = 'exec'
UNION ALL
SELECT mc.caller_class_name, mc.caller_method_name, mc.caller_method_desc,
mc.callee_class_name, mc.callee_method_name, mc.callee_method_desc, cc.depth + 1
FROM method_call_table mc
JOIN call_chain cc ON mc.callee_class_name = cc.caller_class_name
AND mc.callee_method_name = cc.caller_method_name
AND mc.callee_method_desc = cc.caller_method_desc
WHERE cc.depth < 10
)
SELECT DISTINCT caller_class_name, caller_method_name, depth
FROM call_chain
ORDER BY depth;
也可以编写 Python 脚本实现 DFS/BFS 调用链追踪,灵活度更高。
-- 列出所有 Spring Controller
SELECT class_name FROM spring_controller_table;
-- 列出所有 HTTP 映射(API 入口)
SELECT class_name, method_name, restful_type, path
FROM spring_method_table
ORDER BY path;
-- 查找特定 URL 模式的处理方法
SELECT class_name, method_name, method_desc, restful_type, path
FROM spring_method_table
WHERE path LIKE '%user%' OR path LIKE '%admin%';
-- 列出所有 Servlet/Filter/Listener
SELECT type_name, class_name FROM java_web_table;
-- 只看 Filter(可能是安全过滤器)
SELECT class_name FROM java_web_table WHERE type_name = 'Filter';
-- 搜索包含关键字的字符串(如密码、密钥等)
SELECT class_name, method_name, value
FROM string_table
WHERE value LIKE '%password%'
OR value LIKE '%secret%'
OR value LIKE '%key%'
OR value LIKE '%token%';
-- 搜索 JNDI/LDAP/RMI 相关字符串
SELECT class_name, method_name, value
FROM string_table
WHERE value LIKE '%jndi%' OR value LIKE '%ldap://%' OR value LIKE '%rmi://%';
-- 搜索 SQL 语句(可能有 SQL 注入风险)
SELECT class_name, method_name, value
FROM string_table
WHERE value LIKE '%SELECT%FROM%'
OR value LIKE '%INSERT%INTO%'
OR value LIKE '%UPDATE%SET%'
OR value LIKE '%DELETE%FROM%';
-- 搜索 IP 地址和 URL
SELECT class_name, method_name, value
FROM string_table
WHERE value LIKE '%://%'
OR value LIKE '%.%.%.%';
-- 查找某个类的所有子类
SELECT class_name, super_class_name
FROM class_table
WHERE super_class_name LIKE '%AbstractController%';
-- 查找某个接口的所有实现类
SELECT class_name, interface_name
FROM interface_table
WHERE interface_name LIKE '%Serializable%';
-- 查找方法实现(接口方法 → 具体实现)
SELECT class_name, method_name, method_desc, impl_class_name
FROM method_impl_table
WHERE method_name = 'doFilter';
-- 查找所有带特定注解的类/方法
SELECT class_name, method_name, anno_name
FROM anno_table
WHERE anno_name LIKE '%RequestMapping%'
OR anno_name LIKE '%GetMapping%'
OR anno_name LIKE '%PostMapping%';
-- 查找 Controller 类注解
SELECT class_name, anno_name
FROM anno_table
WHERE method_name IS NULL
AND anno_name LIKE '%Controller%';
Sink 定义文件:
<plugin_dir>/references/dfs-sink.json该 JSON 文件包含完整的危险方法(sink)列表,每个条目包含
className、methodName、methodDesc三个字段。 进行漏洞检测时,必须读取并解析该文件,然后基于其中的 sink 定义构造 SQL 查询。
Sink 检测流程:
<plugin_dir>/references/dfs-sink.json 文件method_call_table 中是否存在调用:-- 通用 sink 查询模板(根据 dfs-sink.json 中的条目填充参数)
SELECT DISTINCT
caller_class_name, caller_method_name, caller_method_desc
FROM method_call_table
WHERE callee_class_name = '<sink.className>'
AND callee_method_name = '<sink.methodName>'
AND callee_method_desc = '<sink.methodDesc>';
dfs-sink.json 覆盖的漏洞类型包括但不限于:
| 漏洞类型 | 典型 Sink |
|---|---|
| RCE(远程代码执行) | Runtime.exec、ProcessBuilder.start、ScriptEngine.eval |
| JNDI 注入 | InitialContext.lookup、Context.lookup |
| LDAP 注入 | DirContext.search、LdapContext.search |
| SQL 注入 | Statement.execute/executeQuery/executeUpdate、Connection.prepareStatement/prepareCall |
| 反序列化 | ObjectInputStream.readObject、XMLDecoder.readObject、Yaml.load、JSON.parseObject、XStream.fromXML 等 |
| 文件操作 | FileInputStream/FileOutputStream/RandomAccessFile 构造、File.delete |
| SSRF | URL.openConnection、HttpURLConnection.connect |
| 类加载 | BCEL ClassLoader.loadClass |
注意:dfs-sink.json 中的
methodDesc是精确匹配的,确保查询时使用完整的描述符。
批量 Sink 检测示例(Python):
import json
import sqlite3
# 读取 sink 定义
with open('<plugin_dir>/references/dfs-sink.json', 'r') as f:
sinks = json.load(f)
conn = sqlite3.connect('jar-analyzer.db')
for sink in sinks:
cursor = conn.execute("""
SELECT DISTINCT caller_class_name, caller_method_name, caller_method_desc
FROM method_call_table
WHERE callee_class_name = ?
AND callee_method_name = ?
AND callee_method_desc = ?
""", (sink['className'], sink['methodName'], sink['methodDesc']))
results = cursor.fetchall()
if results:
print(f"\n=== {sink['boxName']} ===")
for row in results:
print(f" {row[0]}.{row[1]} {row[2]}")
conn.close()
重要:SQL 查询只能发现方法调用关系,无法判断数据流和上下文。 必须使用
--decompile反编译可疑类的源码,从具体代码中确认问题是否真实存在。
当通过 SQL 分析发现可疑调用后,使用反编译功能查看完整源码:
java -jar <plugin_dir>/bin/jar-analyzer-engine-1.2.0.jar \
-j <target_jar_path> \
-d <fully.qualified.ClassName>
类名使用
.分隔格式(如com.example.MyController),而非数据库中的/分隔格式。 数据库中查到的类名是/分隔的,需要替换为.再传给-d参数。
反编译确认要点:
示例:SQL 查询发现 com/example/controller/FileController 的 upload 方法调用了 FileOutputStream.<init>,反编译确认:
java -jar <plugin_dir>/bin/jar-analyzer-engine-1.2.0.jar \
-j app.jar \
-d com.example.controller.FileController
查看反编译结果中 upload 方法是否对文件名做了路径穿越防护、文件类型校验等。
dfs-sink.json,批量检测所有已知危险方法调用--decompile 查看源码,确认数据流是否可控、是否有安全防护| 优先级 | 漏洞类型 | 危害程度 |
|---|---|---|
| P0 | RCE(命令执行)、反序列化 | 严重 |
| P1 | SQL 注入、JNDI 注入、SpEL 注入 | 高 |
| P2 | SSRF、XXE、任意文件读写 | 高 |
| P3 | 文件上传、路径穿越 | 中 |
| P4 | 信息泄露、硬编码密钥 | 中 |
/ 分隔格式. 分隔格式method_desc 是精确匹配的关键,避免因方法重载导致误判callee_jar_id = -1 表示被调用方法来自 JDK/外部库(不在分析的 JAR 中)LIMIT 限制结果数量sqlite3 命令行查询,不可用时再使用 Python