SuperAPI AI Directory

java-route-tracer

Coding & development

View repository

Updated 10-16 06:51

About this skill

Java Route Tracer - Route Call Chain Tracing

Based on the route specified by the user, trace the complete call chain from the entry point to the final usage point, and output hierarchical call information.Suitable for parameter flow tracing of multiple vulnerability types.

Core Features

Only output call chain information, without performing vulnerability detection or security recommendations.

Output content includes:

  • Complete HTTP packet - Request template directly usable in Burp Suite
  • Detailed parameter definitions - The name, type, and nested structure of each parameter
  • Hierarchical call relationships - Controller → Service → DAO → parent class
  • Parameter flow tracing - The complete path from the HTTP entry point to the final usage point
  • Parameter variable name tracing - Changes in the variable name of the same parameter across different classes
  • Final usage point annotation - How the parameter is used at the final layer

Applicable Vulnerability Types

Vulnerability Type Trace Final Usage Point
SQL Injection sql + param、Statement.execute()、MyBatis ${}, Hibernate HQL concatenation
Command Injection Runtime.exec(cmd)、ProcessBuilder(cmd)
SSRF HttpClient.execute(url)、URL.openConnection()、RestTemplate
XSS response.getWriter().write(), template engine output,@ResponseBody
File Operations new File(path)、FileInputStream()、Files.read()
XXE DocumentBuilder.parse()、SAXParser、XMLReader
Deserialization ObjectInputStream.readObject()、JSON.parseObject()
LDAP Injection DirContext.search(filter)、LdapTemplate
Expression Injection SpelExpression.getValue()、OGNL、MVEL、Freemarker
Path Traversal new File(basePath + userInput)、Paths.get()

Workflow

1. Receive user input

User provides:

  • Route path: such as /admin/user_login.action or /api/faceCapture
  • Project path: the directory where the source code or decompiled files are located

2. Locate entry point and method identification

Locate the route entry class according to the framework type:

Framework Entry Locating Method
Spring MVC @RequestMapping annotation matching
Struts 2 action configuration in struts.xml
Servlet web.xml or @WebServlet
JAX-RS @Path annotation matching

Important note: When the entry class contains multiple business methods (for example, a Web Service has multiple interface methods, or a Controller has multiple endpoint methods), the skill will automatically identify and trace all methods. For detailed implementation strategy, please refer to:multi-method-tracing.md

2.1 Multi-method tracing execution flow (mandatory requirement)

The following steps must be strictly followed, using the TodoWrite tool to manage tasks:

Step 1: Count all methods

First scan the entry class, identify all methods that need to be traced, and output the method list:

正在扫描入口类: UserQueryServiceImpl

发现以下 10 个方法需要追踪:
1. getBasicQuery(searchJson, pageJson, extend)
2. getAdvancedQuery(searchJson, pageJson, extend)
3. getDetailQuery(searchJson, pageJson, extend)
4. getStatisticsQuery(searchJson, pageJson, extend)
5. getExportQuery(searchJson, pageJson, extend)
... (列出所有方法)
10. getReportQuery(searchJson, pageJson, extend)

共计: 10 个方法

Step 2: Create TodoList tasks

The TodoWrite tool must be used, adding each method as an independent task:

TodoWrite([
    {"content": "追踪方法 1/10: getBasicQuery", "status": "pending", "activeForm": "追踪 getBasicQuery"},
    {"content": "追踪方法 2/10: getAdvancedQuery", "status": "pending", "activeForm": "追踪 getAdvancedQuery"},
    {"content": "追踪方法 3/10: getDetailQuery", "status": "pending", "activeForm": "追踪 getDetailQuery"},
    {"content": "追踪方法 4/10: getStatisticsQuery", "status": "pending", "activeForm": "追踪 getStatisticsQuery"},
    # ... 所有 10 个方法
    {"content": "追踪方法 10/10: getReportQuery", "status": "pending", "activeForm": "追踪 getReportQuery"},
    {"content": "生成总索引文件", "status": "pending", "activeForm": "生成总索引"}
])

Step 3: Execute tasks one by one (optimization strategy)

Execute each task in TodoList order, and adopt different tracing strategies according to the number of interfaces:

Interface Number Tracing Strategy Report Content
1st interface Complete trace chain Includes all levels, branches, variable tracing, and controllability determination
The 2nd and subsequent interfaces Simplified trace chain Must include: request template + method parameter definitions + call chain + Sink identification + controllability determination

Execution flow:

  1. Mark the current task as in_progress
  2. Select the tracing strategy based on the interface sequence number
  3. Generate the corresponding type of report file
  4. Mark the task as completed
  5. Continue to the next task
--- 方法 1/10: getBasicQuery ---
状态: in_progress
[完整追踪链...]
[生成报告: myproject_trace_getBasicQuery_20260205.md]
状态: completed ✅

--- 方法 2/10: getAdvancedQuery ---
状态: in_progress
[简化追踪链...]
[生成报告: myproject_trace_getAdvancedQuery_20260205.md (简化版)]
状态: completed ✅

--- 方法 3/10: getDetailQuery ---
状态: in_progress
[简化追踪链...]
[生成报告: myproject_trace_getDetailQuery_20260205.md (简化版)]
状态: completed ✅

... 继续直到所有任务完成 ...

Step 4: Complete verification

After all method tracing is complete:

  1. Generate the master index file
  2. Verify the number of generated files
  3. Output the completion report
# 验证命令
ls route_tracer/{route_name}/*.md | wc -l
# 期望结果: 11 (10个方法报告 + 1个总索引)

2.2 Interruption recovery mechanism

If execution is interrupted, when continuing next time you must:

  1. Check the already generated report files
  2. Compare against the method list to identify incomplete methods
  3. Create TodoList tasks only for the incomplete methods
  4. Continue execution
# 检查已完成的方法
existing_files = ls("/path/to/route_tracer/{route_name}/*.md")
completed_methods = [extract_method_name(f) for f in existing_files]

# 创建剩余任务
remaining_tasks = []
for method in all_methods:
    if method not in completed_methods:
        remaining_tasks.append({
            "content": f"追踪方法: {method}",
            "status": "pending",
            "activeForm": f"追踪 {method}"
        })

TodoWrite(remaining_tasks)

2.3 Mandatory rules

Rule Description
Must count Before starting, you must count and output the number of all methods
Must use TodoList You must use TodoWrite to add each method as a task
Interface optimization strategy When the number of interfaces > 3, adopt the following optimization plan: - 1st interface: generate a complete call chain trace (including all levels, branches, variable tracing) - 2nd and subsequent interfaces: generate only the complete Burp Suite data packet + simple trace chain (excluding detailed code and branch determination)
Must mark status Immediately mark each task as completed after it is finished
Ending early is prohibited Ending is prohibited when there are pending tasks in the TodoList
Must verify quantity Before ending, you must verify the number of generated files

2.4 File generation rules (mandatory)

All interface quantities uniformly use the following strategy, with no need for batch processing:

Interface sequence number Report type Content
1st Full version All levels, branches, variable tracing, controllability determination (approximately 20000-30000 characters)
2nd and subsequent Simplified version Request template + method parameter definitions + call chain + Sink identification + controllability determination (approximately 2000-4000 characters)

File naming convention:

Rule Format
✅ Correct {项目名}_trace_{方法名}_{时间戳}.md
❌ Incorrect {方法名}_{时间戳}.md (missing project prefix)

Variable replacement check (mandatory):

When generating each simplified report, you must ensure the following content is correctly replaced (retaining template variables is prohibited):

Check item Incorrect example Correct example
Method name ${method} queryUserById
Route path /api/${method} /biz/ws/userService → queryUserById
Service implementation class ${ServiceImpl} UserServiceImpl
SOAP method tag <web:${method}> <web:queryUserById>
Call chain method ${ServiceImpl}.${method}() UserServiceImpl.queryUserById()

File content verification:

After generating each file, you must check:

  1. File nameContains the project prefix (e.g. myproject_trace_)
  2. File contentContains no ${...} form of unreplaced variables
  3. Method nameCorrectly displayed in the report title, data packets, and call chain

2.5 Simplified version must include content (mandatory)

Must include Description Cannot be omitted
HTTP/SOAP request template Placeholder format {{param}}, used to illustrate the structure ✅
Example test data packet A complete data packet containing actual test values, which can be used directly for Burp testing ✅
Parameter definition table specific to the method Read from the method code signature; do not assume ✅
Call chain hierarchy diagram [L1] → [L2] → [Sink] format ✅
Sink identification Identify the final usage point type of the method ✅
Controllability determination conclusion Controllability determination of the method parameters ✅

2.5.1 Test data packet generation rules (mandatory)

Test data packets must contain actual testable values; placeholders are prohibited:

Java type Placeholder (prohibited) Actual value generation rule
String (ID type) {{userId}} Numeric string such as 1001
String (name type) {{name}} Meaningful test value such as testUser
String (date type) {{date}} Standard format such as 2026-01-01
String (path type) {{path}} Valid path such as /tmp/test.txt
String (URL type) {{url}} Complete URL such as http://example.com/api
int/Integer {{count}} Number such as 10
boolean/Boolean {{flag}} true or false
JSON string {{xxxJson}} Complete JSON such as {"id":"1","name":"test"}

Method for generating test values:

  1. Extract from code - Look for values in code comments, unit tests, and sample data
  2. Infer from field semantics - Generate reasonable values based on the meaning of the field name (e.g. email → test@example.com)
  3. Infer from type - Use descriptive text for String, reasonable range values for numbers
  4. Use general security test values - Avoid special characters to ensure the request can be sent normally

2.6 Independent method parameter inspection rules (mandatory)

When tracing each method, the following steps must be performed; skipping is prohibited:

Step 1: Read the actual code signature of the method

The actual code must be read to obtain the real parameters; assumptions are prohibited:

方法A: getDictionaryAll(String codeTypes)           → 1个参数
方法B: getCommonQuery(String searchJson, ...)       → 3个参数
方法C: executeCommand(String cmd, String args)      → 2个参数

Step 2: Independently trace the method's call chain to the Sink

Different methods may have different Sink types:

Method example Call chain Sink type
getCommonQuery → DAO → SQL execution SQL
executeTask → Runtime.exec() COMMAND
fetchUrl → HttpClient.get() HTTP
parseXml → DocumentBuilder.parse() XML
getDictionaryAll → Map.get() No sensitive Sink

Step 3: Determine the controllability of the method parameters

Determine based on the Sink type actually traced for the method:

Sink type Key determination points
SQL Whether the parameter is concatenated into SQL
COMMAND Whether the parameter is passed to command execution
HTTP Whether the parameter is used to construct a URL
FILE Whether the parameter is used for a file path
XML Whether the parameter is passed to an XML parser
No sensitive Sink Mark as "no sensitive operation"

Step 4: Output the independent determination result for this method

Prohibited actions:

  • ❌ Prohibited to write "refer to the parameter definition of the 1st interface"
  • ❌ Prohibited to reuse the controllability conclusions of other methods
  • ❌ Prohibited to assume that all methods have the same parameters or Sink types

2.7 Pre-generation checklist for the simplified version (must be executed for each method)

# Check item Must be executed
1 Read the code signature of this method to obtain the actual parameter list ☐
2 Trace the call chain of this method to the final usage point ☐
3 Identify the Sink type of this method (SQL/COMMAND/HTTP/FILE/XML/none) ☐
4 Determine the controllability of this method's parameters ☐
5 Output the controllability determination table for this method ☐

3. Trace the call chain

Starting from the entry method, trace layer by layer:

Controller/Action 层
    ↓ 调用
Service/Manager 层
    ↓ 调用
DAO/Repository 层
    ↓ 执行
SQL/数据库操作

Tracing rules:

  1. Identify method calls - Check the this.xxx() in the method body or method calls on injected objects
  2. Track dependency injection - Identify @Autowired、@Resource, objects injected via constructor
  3. Track parent class methods - If calling super.xxx() or an inherited method, trace to the parent class
  4. Record parameter passing - Record how parameters are passed from the upper layer to the lower layer

4. Decompilation support

When source code is unavailable, use the CFR decompiler (see java-shared/DECOMPILE_STRATEGY.md):

# 反编译单个文件
java -jar {CFR_JAR} /path/to/SomeClass.class --outputdir {output_path}/decompiled

# 反编译目录
find /path/to/classes -name "*.class" | xargs java -jar {CFR_JAR} --outputdir {output_path}/decompiled

# 批量反编译
java -jar {CFR_JAR} /path/to/A.class /path/to/B.class --outputdir {output_path}/decompiled

Output format

Strictly generate the output file according to the fill-in template in the references/ directory.

Scenario Template File naming
1st interface (full version) OUTPUT_TEMPLATE_FULL.md {project_name}_trace_{method_name}_{YYYYMMDD_HHMMSS}.md
2nd+ interface (simplified version) OUTPUT_TEMPLATE_SIMPLE.md {project_name}_trace_{method_name}_{YYYYMMDD_HHMMSS}.md
Multi-method index OUTPUT_TEMPLATE_INDEX.md {project_name}_trace_all_methods_{YYYYMMDD_HHMMSS}.md

Key rules:

  • All [fill in] placeholders must be replaced with actual content
  • Each method must be independently traced to the Sink; it is prohibited to reuse the conclusions of other methods
  • Multi-method routing must generate an index file
  • General specification reference: java-shared/OUTPUT_STANDARD.md

Single-method routing

File naming: {项目名}_audit/route_tracer/{路由名}/{项目名}_trace_{路由标识}_{时间戳}.md

Directory structure:

{project_name}_audit/
└── route_tracer/
    └── {route_name}/
        └── {project_name}_trace_{route_id}_20260204.md

Multi-interface method routing (important)

When the entry class contains multiple business methods (such as a Web Service or a Controller with multiple endpoints), an independent tracing report file must be generated for each method.

File naming rules:

  • Single method report:{项目名}_trace_{方法名}_{时间戳}.md
  • Master index report:{项目名}_trace_all_methods_{时间戳}.md

Directory structure:

{project_name}_audit/
└── route_tracer/
    └── {route_name}/
        ├── {project_name}_trace_getBasicQuery_20260204.md        # 方法1
        ├── {project_name}_trace_getAdvancedQuery_20260204.md     # 方法2
        ├── {project_name}_trace_getDetailQuery_20260204.md       # 方法3
        ├── {project_name}_trace_getImageQuery_20260204.md        # 方法N
        ├── ... (每个方法一个独立文件)
        └── {project_name}_trace_all_methods_20260204.md           # 总索引

Route name description:

  • The route name is extracted from the route path, removing the leading slash and special characters
  • For example:/biz/ws/userService → biz_ws_userService
  • For example:/api/user/login.action → api_user_login

Execution flow:

正在扫描入口类: UserQueryServiceImpl

✅ 发现 10 个入口方法

--- 方法 1/10: getBasicQuery ---
[生成独立报告: myproject_trace_getBasicQuery_20260204.md]

--- 方法 2/10: getAdvancedQuery ---
[生成独立报告: myproject_trace_getAdvancedQuery_20260204.md]

...

✅ 所有 10 个方法追踪完成
✅ 生成总索引: myproject_trace_all_methods_20260204.md

Master index report content:

# /api/ws/userQuery Web Service 所有方法追踪索引

生成时间: 2026-02-04
入口类: UserQueryServiceImpl
方法总数: 10

## 方法清单

| # | 方法名 | 参数列表 | 详细报告 |
|:--|:-------|:---------|:---------|
| 1 | getBasicQuery | searchJson, pageJson, extend | [查看](myproject_trace_getBasicQuery_20260204.md) |
| 2 | getAdvancedQuery | searchJson, pageJson, extend | [查看](myproject_trace_getAdvancedQuery_20260204.md) |
| 3 | getDetailQuery | searchJson, pageJson, extend | [查看](myproject_trace_getDetailQuery_20260204.md) |
| ... | ... | ... | ... |

For detailed implementation strategy, please refer to:multi-method-tracing.md

Output template

Complete tracing chain (applicable to the 1st interface)

Complete call chain tracing report, including all levels, branches, variable tracing, and other content.

# 路由调用链追踪报告

**追踪路由**: `/admin/image/getImageCapture.action`
**生成时间**: 2026-02-04
**项目路径**: /path/to/project

---

## 1. HTTP 请求数据包

### 1.1 完整请求模板

```http
POST /admin/image/getImageCapture.action HTTP/1.1
Host: {{host}}
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID={{session}}

searchJson={{searchJson}}&pageJson={{pageJson}}&extend={{extend}}
```

### 1.2 参数详细定义

#### 顶层参数

| 参数名 | Java类型 | HTTP位置 | 必填 | 说明 |
|:-------|:---------|:---------|:-----|:-----|
| searchJson | String | Body | 是 | JSON格式,反序列化为 ImageCaptureBean |
| pageJson | String | Body | 是 | JSON格式,反序列化为 Page<ImageCapture> |
| extend | String | Body | 否 | 扩展参数 |

#### pageJson 内部结构 (Page<ImageCapture>)

| 字段名 | Java类型 | 说明 | 最终使用位置 |
|:-------|:---------|:-----|:-------------|
| orderBy | String | 排序字段 | **AbstractDao.findSql():234 - SQL拼接** |
| order | String | 排序方向 (asc/desc) | **AbstractDao.findSql():234 - SQL拼接** |
| pageSize | int | 每页条数 | 分页查询 |
| currentPage | int | 当前页码 | 分页查询 |

#### searchJson 内部结构 (ImageCaptureBean)

| 字段名 | Java类型 | 说明 |
|:-------|:---------|:-----|
| userBean | UserBean | 用户信息对象 |
| startTime | String | 开始时间 |
| endTime | String | 结束时间 |
| deviceIds | List<String> | 设备ID列表 |

### 1.3 测试用数据包示例

```http
POST /admin/image/getImageCapture.action HTTP/1.1
Host: 192.168.1.100:8080
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=ABC123

searchJson={"userBean":{"loginName":"admin"},"startTime":"2026-01-01","endTime":"2026-02-01"}&pageJson={"orderBy":"id","order":"desc","pageSize":10,"currentPage":1}&extend=
```

---

## 2. 调用链层级追踪

### [Level 1] Action 入口层

**文件**: `com/example/web/action/ImageCaptureAction.java:125`
**类名**: `ImageCaptureAction`
**方法签名**:
```java
public String getImageCapture(String searchJson, String pageJson, String extend)
```

**完整代码:**
```java
public String getImageCapture(String searchJson, String pageJson, String extend) {
    // pageJson 反序列化为 Page 对象
    Page<ImageCapture> page = (Page)JsonUtils.fromJson(pageJson, (new TypeToken<Page<ImageCapture>>() {
    }).getType(), (String)null);

    this.defaultImageCaptureSearchOrder(page);

    // searchJson 反序列化为 ImageCaptureBean 对象
    ImageCaptureBean searchBean = (ImageCaptureBean)JsonUtils.fromJson(searchJson, ImageCaptureBean.class, (String)null);

    if (searchBean.getUserBean() != null && StringUtil.isEmpty(searchBean.getUserBean().getHostLoginIp())) {
        String addressIp = WebServiceUtil.getWebServiceIp();
        if (StringUtil.isEmpty(addressIp)) {
            addressIp = searchBean.getUserBean().getLoginServerName();
        }
        searchBean.getUserBean().setHostLoginIp(addressIp);
    }

    searchBean.setSecordExcute(false);
    String json = WebServiceUtil.valiatePam((new TypeToken<ReturnMsgBean<ImageCapture>>() {
    }).getType(), new Object[]{page, searchBean});

    if (json == null) {
        // 关键调用: 传递 searchBean, page, extend 到 Manager 层
        json = this.imageCaptureManager.getImageCaptureJson(searchBean, page, extend);
    }

    return json;
}
```

**参数转换:**

| HTTP参数 | 转换后类型 | 转换后变量名 | 传递到下一层 |
|:---------|:-----------|:-------------|:-------------|
| pageJson (String) | Page<ImageCapture> | page | ✅ |
| searchJson (String) | ImageCaptureBean | searchBean | ✅ |
| extend (String) | String | extend | ✅ |

**Page对象关键字段:**
- `page.orderBy` ← pageJson.orderBy (String类型)
- `page.order` ← pageJson.order (String类型)

**下一层调用**: `this.imageCaptureManager.getImageCaptureJson(searchBean, page, extend)`

---

### [Level 2] Manager 服务层

**文件**: `com/example/service/ImageCaptureManager.java:89`
**类名**: `ImageCaptureManager`
**方法签名**:
```java
public String getImageCaptureJson(ImageCaptureBean searchBean, Page<ImageCapture> page, String extend)
```

**完整代码:**
```java
public String getImageCaptureJson(ImageCaptureBean searchBean, Page<ImageCapture> page, String extend) {
    // 关键调用: 将 page 传递给 DAO 层
    Page<ImageCapture> result = this.imageCaptureDao.getImageCapturePage(searchBean, page);
    return JsonUtils.toJson(result);
}
```

**参数传递:**

| 接收参数 | 类型 | 传递到下一层 |
|:---------|:-----|:-------------|
| searchBean | ImageCaptureBean | ✅ |
| page | Page<ImageCapture> | ✅ (含 orderBy, order) |
| extend | String | ❌ (未传递) |

**下一层调用**: `this.imageCaptureDao.getImageCapturePage(searchBean, page)`

---

### [Level 3] DAO 数据访问层

**文件**: `com/example/dao/ImageCaptureDao.java:56`
**类名**: `ImageCaptureDao`
**父类**: `AbstractDao<ImageCapture>`
**方法签名**:
```java
public Page<ImageCapture> getImageCapturePage(ImageCaptureBean searchBean, Page<ImageCapture> page)
```

**完整代码:**
```java
public Page<ImageCapture> getImageCapturePage(ImageCaptureBean searchBean, Page<ImageCapture> page) {
    String sql = buildQuerySql(searchBean);
    // 关键调用: 调用父类 AbstractDao.findSql(),传入 page 对象
    return super.findSql(sql, page);
}
```

**参数传递:**

| 接收参数 | 类型 | 传递到下一层 |
|:---------|:-----|:-------------|
| searchBean | ImageCaptureBean | ❌ (用于构建SQL) |
| page | Page<ImageCapture> | ✅ (传递给父类) |

**下一层调用**: `super.findSql(sql, page)` → 父类 `AbstractDao.findSql()`

---

### [Level 4] 父类基础层 (最终使用点)

**文件**: `com/example/dao/base/AbstractDao.java:234`
**类名**: `AbstractDao<T>`
**方法签名**:
```java
protected Page<T> findSql(String sql, Page<T> page)
```

**完整代码:**
```java
protected Page<T> findSql(String sql, Page<T> page) {
    if (page.getOrderBy() != null) {
        // ⚠️ 最终使用点: orderBy 和 order 直接拼接到 SQL 语句
        sql = sql + " ORDER BY " + page.getOrderBy() + " " + page.getOrder();
    }
    // 执行 SQL 查询
    return executeQuery(sql, page);
}
```

**参数最终使用:**

| 参数 | 类型 | 使用方式 | 代码位置 |
|:-----|:-----|:---------|:---------|
| page.getOrderBy() | String | **直接拼接到 SQL** | AbstractDao.java:235 |
| page.getOrder() | String | **直接拼接到 SQL** | AbstractDao.java:235 |

---

## 3. 调用链总结图

```
HTTP Request
│
├─ searchJson (String) ──→ ImageCaptureBean searchBean
│                              └─ userBean: UserBean
│                              └─ startTime: String
│                              └─ endTime: String
│
├─ pageJson (String) ────→ Page<ImageCapture> page
│                              ├─ orderBy: String ─────────────────────┐
│                              ├─ order: String ───────────────────────┤
│                              ├─ pageSize: int                        │
│                              └─ currentPage: int                     │
│                                                                      │
└─ extend (String) ──────→ (未向下传递)                                │
                                                                       │
┌──────────────────────────────────────────────────────────────────────┘
│
▼ 参数流向追踪

[L1] ImageCaptureAction.getImageCapture()
      │
      │  page (含 orderBy, order), searchBean
      ▼
[L2] ImageCaptureManager.getImageCaptureJson()
      │
      │  page (含 orderBy, order), searchBean
      ▼
[L3] ImageCaptureDao.getImageCapturePage()
      │
      │  page (含 orderBy, order)
      ▼
[L4] AbstractDao.findSql()
      │
      └──→ sql = sql + " ORDER BY " + page.getOrderBy() + " " + page.getOrder()
           ▲                              ▲
           │                              │
           └── orderBy 直接拼接 ──────────┴── order 直接拼接
```

---

## 4. 参数变量名追踪表(核心)

**追踪同一参数在不同类中的变量名变化:**

### 4.1 pageJson.orderBy 参数追踪

| 层级 | 类名 | 变量名 | 类型 | 代码位置 | 说明 |
|:-----|:-----|:-------|:-----|:---------|:-----|
| HTTP | - | `pageJson` | String | 请求Body | 原始JSON字符串 |
| L1 | ImageCaptureAction | `pageJson` → `page.orderBy` | Page.orderBy: String | :125 | JsonUtils.fromJson()反序列化 |
| L2 | ImageCaptureManager | `page.orderBy` | Page.orderBy: String | :89 | 参数名不变,直接传递 |
| L3 | ImageCaptureDao | `page.orderBy` | Page.orderBy: String | :56 | 参数名不变,传递给父类 |
| L4 | AbstractDao | `page.getOrderBy()` | String | :235 | **最终使用: SQL拼接** |

### 4.2 pageJson.order 参数追踪

| 层级 | 类名 | 变量名 | 类型 | 代码位置 | 说明 |
|:-----|:-----|:-------|:-----|:---------|:-----|
| HTTP | - | `pageJson` | String | 请求Body | 原始JSON字符串 |
| L1 | ImageCaptureAction | `pageJson` → `page.order` | Page.order: String | :125 | JsonUtils.fromJson()反序列化 |
| L2 | ImageCaptureManager | `page.order` | Page.order: String | :89 | 参数名不变 |
| L3 | ImageCaptureDao | `page.order` | Page.order: String | :56 | 参数名不变 |
| L4 | AbstractDao | `page.getOrder()` | String | :235 | **最终使用: SQL拼接** |

### 4.3 searchJson 参数追踪

| 层级 | 类名 | 变量名 | 类型 | 代码位置 | 说明 |
|:-----|:-----|:-------|:-----|:---------|:-----|
| HTTP | - | `searchJson` | String | 请求Body | 原始JSON字符串 |
| L1 | ImageCaptureAction | `searchJson` → `searchBean` | ImageCaptureBean | :128 | JsonUtils.fromJson()反序列化 |
| L2 | ImageCaptureManager | `searchBean` | ImageCaptureBean | :89 | 参数名不变 |
| L3 | ImageCaptureDao | `searchBean` | ImageCaptureBean | :56 | **最终使用: buildQuerySql()** |

### 4.4 变量名变化示例(当参数名在不同层改变时)

```
HTTP: pageJson (String)
       ↓ JsonUtils.fromJson()
L1 ImageCaptureAction: page (Page<ImageCapture>)
       ↓ 方法参数传递
L2 ImageCaptureManager: page (Page<ImageCapture>)  ← 同名
       ↓ 方法参数传递
L3 ImageCaptureDao: page (Page<ImageCapture>)  ← 同名
       ↓ super.findSql(sql, page)
L4 AbstractDao: page (Page<T>)  ← 泛型类型变化
       ↓ page.getOrderBy()
最终使用: sql = sql + " ORDER BY " + page.getOrderBy()
```

### 4.5 完整参数追踪汇总

| 原始HTTP参数 | L1变量名 | L2变量名 | L3变量名 | L4变量名 | 最终使用 |
|:-------------|:---------|:---------|:---------|:---------|:---------|
| pageJson | page | page | page | page | page.getOrderBy() → SQL拼接 |
| pageJson.orderBy | page.orderBy | page.orderBy | page.orderBy | page.getOrderBy() | SQL ORDER BY 子句 |
| pageJson.order | page.order | page.order | page.order | page.getOrder() | SQL ORDER BY 子句 |
| searchJson | searchBean | searchBean | searchBean | - | buildQuerySql() |
| extend | extend | - | - | - | 未向下传递 |

5. Parameter Actual Usage Check (CRITICAL - Prevent Vulnerability Misjudgment)

Trace each parameter from the HTTP entry point to the final usage point, and determine whether the parameter truly participates in sensitive operations.

This check is crucial for accurately determining vulnerabilities and can avoid misjudging cases where "a parameter is passed but not used" as vulnerabilities.

5.1 Check Description

Status Meaning Effect on Vulnerability Determination
✅ Used The parameter value directly or indirectly participates in sensitive operations Must further check whether a vulnerability exists
❌ Not Used The parameter is passed but does not participate in sensitive operations (overwritten by hardcoding/ignored) Exclude vulnerability
⚠️ Partially Used Some fields of the parameter are used, while some are not used Only check the fields that are used

5.2 "Hardcoded Override" Scenarios for Each Vulnerability Type

Vulnerability Type Parameter Hardcoded Override Scenario Conclusion
SQL Injection page.orderBy SQL is already hardcoded order by createTime desc Parameter not used
Command Injection cmd Code hardcoded Runtime.exec("ls -la") Parameter not used
SSRF url Code hardcoded httpClient.get("http://internal/api") Parameter not used
File Operation path Code hardcoded new File("/tmp/fixed.txt") Parameter not used
XXE xml Code uses a fixed XML template Parameter not used
Expression Injection expr Code hardcoded expression SpEL.parse("#{fixed}") Parameter not used

5.3 Parameter Usage Checklist (Output Template)

## 参数实际使用检查

| 参数 | Sink类型 | 覆盖类型 | 覆盖条件 | 可控性结论 | 可控场景 |
|:-----|:---------|:---------|:---------|:-----------|:---------|
| page.orderBy | SQL ORDER BY | 条件覆盖 | `isEmpty(orderBy)` | ⚠️ 条件可控 | 非空时可控 |
| page.order | SQL ORDER BY | 无覆盖 | - | ✅ 完全可控 | 任意值 |
| cmd | Runtime.exec | 无覆盖 | - | ✅ 完全可控 | 任意值 |
| url | HTTP请求 | 安全检查覆盖 | `!isInternalUrl(url)` | ⚠️ 条件可控 | 外网URL时可控 |
| path | File操作 | 白名单覆盖 | `!allowedPaths.contains()` | ⚠️ 白名单内可控 | /tmp, /data 等 |
| searchBean.keyword | SQL WHERE | 无条件覆盖 | 总是覆盖 | ❌ 不可控 | 无 |

Controllability conclusion description:

Conclusion Meaning Audit Requirement
✅ Fully Controllable The parameter has no override at all, and user input reaches the Sink directly Must audit the security of the Sink point
⚠️ Conditionally Controllable The parameter is controllable under specific conditions Need to verify bypass conditions before auditing
❌ Not Controllable The parameter is unconditionally overwritten or safely handled The vulnerability for this parameter can be excluded

5.4 General Override Condition Identification Rules (Applicable to All Vulnerability Types)

After tracing to a parameter assignment operation, override conditions must be checked. This rule applies to any type of parameter:

Override Type Code Feature Controllability Determination Applicable Scenario
Unconditional Override x = "hardcoded"; (not inside if) ❌ Not Controllable All vulnerability types
Empty Value Protection Override if (isEmpty(x)) { x = default; } ⚠️ Controllable when non-empty All vulnerability types
null Protection Override if (x == null) { x = default; } ⚠️ Controllable when non-null All vulnerability types
Whitelist Override if (!list.contains(x)) { x = default; } ⚠️ Controllable within whitelist All vulnerability types
Security check coverage if (!isAllowed(x)) { x = safe; } ⚠️ Controllable when check is bypassed SSRF/File/Command
Format validation coverage if (!isValid(x)) { x = default; } ⚠️ Controllable when format matches All vulnerability types
Conditional branch coverage if (cond) { x = default; } ⚠️ Controllable when condition is not met All vulnerability types

Common coverage condition identification (general):

Condition type Identification pattern Controllable scenario
Null check isEmpty(), isBlank(), == null, length() == 0 Controllable when not null
Whitelist check contains(), Arrays.asList(), allowedList.contains() Controllable within whitelist
Blacklist check !contains(), blacklist.contains() → Reject Controllable when not in blacklist
Format validation matches(), Pattern.compile(), isValid() Controllable when format matches
Security check isAllowed(), isSafe(), checkSecurity() Controllable when check is bypassed
Range check x > min && x < max, inRange() Controllable within range

Original hardcoded coverage detection rules (still applicable):

Sensitive operation type Hardcoded coverage determination method Example
SQL ORDER BY Check whether the SQL string already contains order by sql + " order by id desc"
SQL WHERE Check whether the condition uses parameterization #{} or a hardcoded value WHERE status = 1
Command execution Check whether the command string uses a hardcoded command exec("ls -la")
HTTP request Check whether the URL uses a hardcoded address get("http://fixed.com")
File operation Check whether the path uses a hardcoded path new File("/tmp/log.txt")
XML parsing Check whether the XML comes from a fixed template parse(FIXED_XML)

5.5 Hardcoded coverage detail output format

When a parameter is found to be overwritten by hardcoding, details must be output:

### 硬编码覆盖详情

#### {参数名} - 被硬编码覆盖

**代码位置**: `{ClassName}.java:{line}`

**覆盖代码**: {展示硬编码覆盖的代码片段}

**判定**:
- {参数}被传递到{方法}
- 但{敏感操作}已经包含硬编码值
- **结论**: ❌ 参数未使用,不存在漏洞

5.6 Parameter actual usage checklist

Before outputting the tracking report, the following checks must be completed:

# Check item Status
1 Identify all parameters passed to the final layer ☐
2 Determine the sensitive operation type of each parameter ☐
3 Check whether hardcoded coverage exists ☐
4 Mark the actual usage status of each parameter ☐
5 Output details for parameters that are "overwritten by hardcoding" ☐
6 Check the semantics of the coverage condition and output a controllability conclusion ☐

6. Parameter controllability determination (CRITICAL - basis for general vulnerability determination)

Applicable to all vulnerability types: SQL injection, command injection, SSRF, file operations, XXE, expression injection, etc.

For detailed determination principles, please refer to:CONTROLLABILITY_ANALYSIS.md

6.1 Core determination process

1. 追踪参数从 HTTP 入口到 Sink 的完整路径
2. 识别路径上所有对参数的赋值/覆盖操作
3. 检查覆盖操作的条件语义(识别代码意图,非模式匹配)
4. 输出可控性结论

6.2 Coverage types and controllability

Coverage type Determination criteria Controllability conclusion
No coverage The parameter is passed directly to the Sink ✅ Fully controllable
Unconditional coverage The assignment is not within any condition ❌ Not controllable
Conditional coverage Assignment within a condition requires semantic determination ⚠️ Controllable condition

6.3 Condition semantic determination (key)

Identify based on code semantics, rather than matching fixed method names:

Semantic type Determination method Controllable scenario
Null protection Condition checks whether the parameter is null; sets a default value when null Controllable when non-null
Whitelist validation Condition checks whether the parameter is in the allowed list Controllable within the whitelist
Security check Condition checks whether the parameter is safe Controllable when bypassing the check

6.4 Output format

Must output the controllability determination table:

| 参数 | Sink类型 | 覆盖类型 | 覆盖条件 | 可控性结论 | 可控场景 |
|:-----|:---------|:---------|:---------|:-----------|:---------|
| {name} | {sink} | {type} | {condition} | {✅/⚠️/❌} | {scenario} |

Must output the controllability summary:

| 可控性类型 | 参数列表 | 审计要求 |
|:-----------|:---------|:---------|
| ✅ 完全可控 | {list} | 必须审计 Sink 安全性 |
| ⚠️ 条件可控 | {list} | 需验证绕过条件 |
| ❌ 不可控 | {list} | 可排除漏洞可能 |

6.5 Sink types

Sink Description
SQL SQL concatenation/execution
COMMAND System command execution
HTTP HTTP request initiation
FILE File read/write operations
XML XML parsing
LDAP LDAP query
EXPRESSION Expression parsing
DESERIALIZE Deserialization
RESPONSE Response output
PATH Path concatenation

7. Branch condition tracking (CRITICAL - avoid vulnerability misjudgment)

When tracking the call chain, all conditional branches must be recorded to ensure whether the code will actually execute is identified!

For detailed determination principles, please refer to:BRANCH_TRACING.md

7.1 Core determination process

1. 识别代码中的条件分支(if/else/switch)
2. 检查每个分支的执行内容
3. 判定敏感操作在哪些分支中执行
4. 输出执行路径结论

7.2 Branch types that must be identified

Identify based on code semantics, rather than matching fixed method names:

Branch type Semantic feature Tracking key points
Environment/platform branch Select different paths based on the runtime environment Annotate the execution content of each environment
Security check branch Perform security validation on the input Annotate the interception condition
Feature toggle branch Determine whether to execute based on configuration Annotate the impact of the toggle state
Null/exception branch Check parameter validity Annotate the early exit condition
Permission determination branch Check user permissions Annotate the permission requirements

7.3 Early exit point identification

Exit type Semantics Must annotate
Security interception exit Security check failed, refuse to continue ⚠️ Security interception
Null protection exit Parameter invalid, return early ⚠️ Early exit
Exception thrown exit Condition not satisfied, throw an exception ⚠️ Exception exit

7.4 Output format

Must output the branch structure:

methodName(param)
    ├─ [if 条件A] → 分支A执行内容
    │      └─→ 敏感操作 ⚠️
    └─ [else] → 默认分支 / return / throw

Must output the execution path conclusion:

| 路径 | 条件 | 敏感操作 | 可利用性 |
|:-----|:-----|:---------|:---------|
| 路径A | {条件} | ✅ 执行 | 可利用 |
| 路径B | {条件} | ❌ 不执行 | 不可利用 |

Tracking strategy

Strategy 1: Dependency injection tracking

Identify Spring/Struts dependency injection:

// Spring
@Autowired
private ImageCaptureManager imageCaptureManager;

// Struts
private ImageCaptureService faceCaptureService;
public void setImageCaptureService(ImageCaptureService service) {
    this.faceCaptureService = service;
}

Track imageCaptureManager.xxx() When called, locate the ImageCaptureManager class.

Strategy 2: Inheritance Chain Tracing

When calling super.xxx() or a parent class method:

public class ImageCaptureDao extends AbstractDao<ImageCapture> {
    public Page<ImageCapture> query(Page<ImageCapture> page) {
        return super.findSql(sql, page);  // 追踪到 AbstractDao
    }
}

Tracing steps:

  1. Identify extends AbstractDao
  2. Search for the findSql method in the parent class
  3. Continue tracing the parent class's parent class (if any)

Strategy 3: Interface Implementation Tracing

When calling an interface method:

@Autowired
private UserService userService;  // 接口类型

userService.getUser(id);  // 需要找到实现类

Tracing steps:

  1. Identify UserService is an interface
  2. Search for the class of implements UserService class
  3. Locate the method of the implementation class

Strategy 4: MyBatis/Hibernate Tracing

For ORM frameworks:

MyBatis:

@Mapper
public interface UserMapper {
    List<User> selectByPage(@Param("page") Page page);
}

Trace to the SQL definition in the corresponding XML file.

Hibernate:

session.createQuery("FROM User WHERE id = " + id);

Identify HQL/SQL directly in the code.


Decompilation Tool Usage

When to Decompile

Scenario Operation
.java source code exists Read and inspect directly
Only .class files exist Use decompile_file
The entire project has only .class files Use decompile_directory
The parent class is in a JAR package First extract the JAR, then decompile_file

Decompilation Command Reference

# 检查 CFR 状态
java -jar {CFR_JAR} --help

# 检查 Java 版本
java -version

# 如果 CFR 不存在,下载
curl -L -o {output_path}/cfr-0.152.jar "https://xget.xi-xu.me/gh/leibnitz27/cfr/releases/download/0.152/cfr-0.152.jar"

# 反编译单个类
java -jar {CFR_JAR} /path/to/AbstractDao.class --outputdir {output_path}/decompiled

# 反编译整个 DAO 包
find /path/to/com/example/dao -name "*.class" | xargs java -jar {CFR_JAR} --outputdir {output_path}/decompiled

Output Specification

Required Information

Each level must include:

  1. File location - Full package path + file name + line number
  2. Class name - Including parent class information (if any)
  3. Method signature - Method name + parameter list + return type
  4. Key code - Show the code snippet that calls the next level
  5. Parameter passing - Explain how parameters are passed to the next level

Prohibited Operations

  • ❌ Do not perform vulnerability detection or vulnerability determination
  • ❌ Do not provide remediation solutions
  • ❌ Do not infer non-existent call relationships
  • ❌ Do not omit any level

Output File Naming

{project_name}_audit/route_tracer/{route_name}/{project_name}_trace_{route_id}_{timestamp}.md

示例:
myproject_audit/route_tracer/biz_ws_userService/myproject_trace_queryUserById_20260204.md

Simple tracing chain (applicable to the 2nd and subsequent interfaces)

Must include the following content: request template + method parameter definition + call chain + Sink identification + controllability determination

# 路由调用链追踪报告(简化版)

**追踪路由**: `{route}`
**方法**: `{method}`
**生成时间**: {date}

---

## 1. HTTP 请求数据包

### 1.1 完整请求模板
```http
{该方法的完整请求模板}

1.2 Method Parameter Definition

Parameter source: Read from the {ClassName}.{method}() method signature

Top-level parameters

Parameter name Java type Description
{param} {type} {desc}

Parameter internal structure (if any)

Field name Java type Description
{field} {type} {desc}

1.3 Test Data Packet Example

{测试数据包}

2. Call Chain Tracing

Call chain levels

[L1] {Class}.{method}()
    ↓
[L2] {Class}.{method}()
    ↓
[Sink] {Sink类型}: {具体位置}

Sink Identification

Sink type Location Description
{SQL/COMMAND/HTTP/FILE/XML/no sensitive Sink} {Class.java:line} {specific operation}

Parameter Passing Relationships

Parameter L1 L2 ... Final use
{param} {var} {var} ... {usage}

3. Controllability Determination

Parameter Sink type Override type Override condition Controllability conclusion Controllable scenario
{param} {sink} {type} {condition} {✅/⚠️/❌/-} {scenario}

Controllability summary:

Type Parameter Audit requirement
✅ Fully controllable {list} Sink security needs to be audited
⚠️ Conditionally controllable {list} Bypass conditions need to be verified
❌ Not controllable {list} Vulnerability possibility can be ruled out
- No sensitive Sink {list} Low risk

**简化版生成注意事项:**
- 必须从该方法实际代码读取参数,禁止假设
- 必须独立追踪该方法的调用链到 Sink
- 必须识别该方法的 Sink 类型(可能与第1个接口不同)
- 必须输出该方法的可控性判定(禁止复用其他方法结论)
- 如果该方法无敏感 Sink,在可控性判定中标注"无敏感Sink,低风险"

---

## 限制与边界

**仅执行以下操作:**
- 追踪指定路由的调用链
- 输出每层的文件位置和方法签名
- 记录参数传递关系
- 生成 HTTP 请求模板

**不执行以下操作:**
- 不进行安全漏洞检测
- 不提供修复方案
- 不判定漏洞等级
- 不检查业务逻辑正确性