Semgrep与AI:智能代码审计规则开发实战(二)
实战篇:用AI为Java代码编写Semgrep规则 - 硬编码密码与SQL注入检测一、环境准备与AI工具选择前言在上一篇中,我们探讨了Semgrep与AI结合的理论基础。现在,让我们进入实战环节,亲身 2025-11-20 03:5:0 Author: www.freebuf.com(查看原文) 阅读量:6 收藏

实战篇:用AI为Java代码编写Semgrep规则 - 硬编码密码与SQL注入检测

一、环境准备与AI工具选择

前言

在上一篇中,我们探讨了Semgrep与AI结合的理论基础。现在,让我们进入实战环节,亲身体验这种协作模式的高效性。本文将聚焦于Java语言,通过两个经典的安全漏洞场景——硬编码密码和SQL注入,一步步演示如何与AI协作,生成精准的Semgrep检测规则。

1763607286_691e82f67159e151874a3.jpeg!small?1763607287291

一、环境准备与AI工具选择

1.1 Semgrep环境配置

首先确保已安装Semgrep:

# 使用pip安装
pip install semgrep

# 或使用Homebrew(macOS)
brew install semgrep

# 验证安装
semgrep --version

1.2 AI工具选择

我们将使用大语言模型作为AI助手,可以选择:

  • OpenAI GPT-4/ChatGPT

  • Claude 3

  • DeepSeek

  • 本地部署的CodeLlama等开源模型

我这里选择是DeepSeek模型。

二、实战一:硬编码密码检测规则

2.1 漏洞场景分析

硬编码密码是Java应用中常见的安全隐患,可能出现在:

  • 数据库连接字符串

  • API密钥配置

  • 加密密钥定义等

2.2 生成含有漏洞的测试代码

生成检测硬编码密码规则测试代码的提示词

你是一名专业的Java安全测试工程师,请为硬编码密码检测规则生成测试代码。

**规则目标:** 检测Java代码中的硬编码密码、密钥等敏感信息

**规则特征:**
- 检测字符串变量赋值中的硬编码密码
- 识别常见的密码相关变量名(password、secret、key等)
- 排除环境变量读取和配置读取的安全用法

**生成要求:**
1. 创建包含10个测试用例的Java类
2. 正例(5个):包含各种硬编码密码的场景
3. 反例(5个):展示安全的使用方式
4. 覆盖不同的变量声明方式(局部变量、静态常量等)

**具体场景要求:**
正例应包含:
- 数据库密码硬编码
- API密钥硬编码  
- 加密密钥硬编码
- 静态常量中的硬编码
- 不同命名风格的密码变量

反例应包含:
- 从环境变量读取密码
- 从配置文件读取
- 从密钥管理服务获取
- 使用占位符等待注入
- 非密码相关的字符串变量

请生成完整的测试代码。

1763607373_691e834d894a2533f21c1.png!small?1763607374373

2.3 检测规则生成

检测规则生成初始提示词

你是一名Java安全专家,请为Semgrep编写一条检测硬编码密码的规则。
要求:
1. 规则ID:java-hardcoded-password
2. 检测Java代码中的硬编码密码
3. 识别常见的密码变量名:password、passwd、pwd、secret、key、token等
4. 匹配字符串字面量赋值,如:String password = "123456"
5. 匹配静态常量定义,如:private static final String API_KEY = "abcd1234"
6. 排除环境变量读取:System.getenv("DB_PASSWORD")
7. 排除配置文件读取:props.getProperty("database.password")
8. 严重级别:ERROR
请提供完整的Semgrep规则YAML格式。

初始生成结果

rules:
  - id: java-hardcoded-password
    message: >
      检测到硬编码密码。硬编码密码存在安全风险,建议使用环境变量或安全配置管理。
    languages: [java]
    severity: ERROR
    patterns:
      - pattern: |
          String $VAR = ...;
      - metavariable-regex:
          metavariable: $VAR
          regex: '(?i)(password|passwd|pwd|secret|key|token)'
      - pattern-not: |
          String $VAR = System.getenv(...);

初始的生成规则比较简单,需要人工进行优化,手动执行规则后可以将返回结果提交大模型,进行多轮的优化改进后,得到符合预期的规则。

1763607503_691e83cf6b0e789d6d305.png!small?1763607504263

实际优化后的规则较长,可以到github上查看完整的项目信息。

1763607521_691e83e1ac334aa2de65f.png!small?1763607522737

实际执行结果。

1763607533_691e83edf28d9b6ac9479.png!small?1763607534829

1763607544_691e83f86c22ea683907c.png!small?1763607545321

三、实战二:SQL注入检测规则

3.1 漏洞场景分析

SQL注入是Web应用中最危险的漏洞之一。在Java中常见于:

  • 使用Statement直接执行拼接的SQL

  • 未使用参数化查询的JDBC操作

  • 动态拼接的HQL/Hibernate查询

2.2 生成含有漏洞的测试代码

生成检测通用SQL注入规则测试代码的提示词

你是一名专业的Java安全测试工程师,请为SQL注入检测规则生成测试代码。
**规则目标:** 检测Java中通过字符串拼接构建SQL查询导致的注入漏洞
**规则特征:**
- 使用污点跟踪模式
- 源:用户输入方法(getParameter等)
- 汇:SQL执行方法(executeQuery等)
- 检测从源到汇的未净化数据流
**生成要求:**
1. 创建包含12个测试用例的Java类
2. 正例(6个):展示各种SQL注入漏洞场景
3. 反例(6个):展示安全的SQL使用方法
4. 覆盖不同的SQL操作和框架
**具体场景要求:**
正例应包含:
- 基本的字符串拼接SQL
- 多参数拼接的复杂SQL
- 存储过程中的SQL拼接
- Hibernate中的原生SQL拼接
- 动态表名/列名拼接
- 批处理操作中的拼接
反例应包含:
- 使用PreparedStatement参数化查询
- 使用命名参数的Hibernate查询
- 使用JPA的Criteria API
- 使用MyBatis的参数映射
- 经过净化的输入处理
- 静态SQL查询(无用户输入)
请生成完整的测试代码。

生成检测JAVA框架SQL注入规则测试代码的提示词

你是一名专业的Java安全测试工程师,请为Java主流框架的SQL注入检测规则生成全面的测试代码。
**检测目标:** 识别Spring Boot、MyBatis、JPA/Hibernate等主流Java框架中的SQL注入漏洞模式
**规则技术特征:**
- 检测模式:污点跟踪分析
- 污染源:@RequestParam、@PathVariable、HttpServletRequest.getParameter()等Web层输入
- 危险汇点:JdbcTemplate、MyBatis Mapper、JPA Repository、Hibernate Session等数据层操作
- 关键路径:用户输入未经验证直接拼接到SQL/ORM查询中
**测试代码生成要求:**
### 正例测试用例(漏洞场景,6个)
1. **Spring JdbcTemplate字符串拼接**
   - 使用`JdbcTemplate.query(String sql)`直接拼接用户输入
   - 动态表名/列名拼接场景
2. **MyBatis ${}注入漏洞**
   - Mapper XML中使用`${param}`直接替换
   - 动态SQL中的不安全拼接
3. **JPA/Hibernate原生SQL拼接**
   - `EntityManager.createNativeQuery()`拼接用户输入
   - Hibernate Session原生SQL拼接
4. **JPA Criteria API误用**
   - 通过字符串拼接构造Predicate条件
   - 动态Order By字段拼接
5. **Spring Data JPA @Query注解漏洞**
   - @Query中使用SpEL表达式或字符串拼接
   - 原生SQL查询中的参数拼接
6. **框架组合使用漏洞**
   - 多层级调用中的SQL拼接
   - 自定义Repository实现中的字符串拼接
### 反例测试用例(安全实践,6个)
1. **Spring JdbcTemplate安全用法**
   - 使用`JdbcTemplate.query(String sql, Object[] args)`
   - 使用NamedParameterJdbcTemplate
2. **MyBatis #{}安全参数化**
   - Mapper XML中使用`#{param}`预编译
   - @Param注解的正确使用
3. **JPA/Hibernate安全查询**
   - 使用JPQL位置参数`:param`
   - 使用Criteria API类型安全查询
4. **Spring Data JPA安全实践**
   - @Query中使用命名参数
   - 使用方法名推导查询
5. **输入验证与净化**
   - 使用Bean Validation注解校验输入
   - 自定义参数绑定和类型转换
6. **框架安全配置**
   - 使用白名单校验动态字段
   - SQL注入防护过滤器配置
**代码规范要求:**
- 每个测试用例包含完整的方法实现
- 使用真实业务场景(用户查询、订单搜索等)
- 包含必要的Spring注解和框架配置
- 添加详细注释说明漏洞原理和安全修复方案
**输出格式示例:**

2.3 检测规则生成

检测JAVA通用SQL注入规则生成初始提示词

你是一名专业的Java安全测试工程师,请为SQL注入检测规则生成测试代码。
**规则目标:** 检测Java中通过字符串拼接构建SQL查询导致的注入漏洞
**规则特征:**
- 使用污点跟踪模式
- 源:用户输入方法(getParameter等)
- 汇:SQL执行方法(executeQuery等)
- 检测从源到汇的未净化数据流
**生成要求:**
1. 创建包含12个测试用例的Java类
2. 正例(6个):展示各种SQL注入漏洞场景
3. 反例(6个):展示安全的SQL使用方法
4. 覆盖不同的SQL操作和框架
**具体场景要求:**
正例应包含:
- 基本的字符串拼接SQL
- 多参数拼接的复杂SQL
- 存储过程中的SQL拼接
- Hibernate中的原生SQL拼接
- 动态表名/列名拼接
- 批处理操作中的拼接
反例应包含:
- 使用PreparedStatement参数化查询
- 使用命名参数的Hibernate查询
- 使用JPA的Criteria API
- 使用MyBatis的参数映射
- 经过净化的输入处理
- 静态SQL查询(无用户输入)
请生成完整的测试代码。

检测JAVA框架SQL注入规则生成初始提示词

你是一名专业的Java安全测试工程师,专注于企业级应用安全检测。请为基于Java主流框架的SQL注入检测规则生成全面的测试代码。
## 检测规则技术规格
**检测模式:** 污点跟踪分析
**目标框架:** Spring Boot, MyBatis, JPA/Hibernate, Spring Data JPA
**技术栈:** Java 8+, Maven/Gradle, 主流ORM框架
## 测试代码生成要求
### 漏洞场景覆盖(正例 - 6个用例)
每个用例应体现从Web层到数据层的完整污点传播路径:
1. **Spring JdbcTemplate字符串拼接漏洞**
   - 场景:REST接口参数直接拼接到JdbcTemplate查询
   - 技术要求:使用`@RequestParam` + `JdbcTemplate.query(String sql)`
2. **MyBatis ${}参数注入漏洞**  
   - 场景:XML Mapper中使用${}进行字符串替换
   - 技术要求:模拟MyBatis动态SQL中的不安全参数绑定
3. **JPA原生SQL拼接漏洞**
   - 场景:EntityManager.createNativeQuery()直接拼接用户输入
   - 技术要求:JPA原生查询中的字符串拼接
4. **Hibernate HQL注入漏洞**
   - 场景:HQL查询中使用字符串拼接构造查询条件
   - 技术要求:Hibernate Session中的HQL拼接
5. **动态Schema/Table名注入**
   - 场景:用户输入用于动态构造表名或排序字段
   - 技术要求:动态DDL操作中的拼接漏洞
6. **批处理操作SQL注入**
   - 场景:批量更新/删除操作中的拼接漏洞
   - 技术要求:JDBC批处理中的字符串拼接
### 安全实践用例(反例 - 6个用例)
展示相同业务场景的安全实现:
1. **Spring JdbcTemplate参数化查询**
   - 安全实践:使用`JdbcTemplate.query(String sql, Object[] params)`
   - 对比:与正例1相同的业务功能
2. **MyBatis #{}参数化映射**
   - 安全实践:XML Mapper中使用#{}进行预编译参数绑定
   - 对比:与正例2相同的动态查询需求
3. **JPA命名参数安全查询**
   - 安全实践:使用JPQL命名参数和参数绑定
   - 对比:与正例3相同的查询功能
4. **Hibernate Criteria安全API**
   - 安全实践:使用类型安全的Criteria API构建查询
   - 对比:与正例4相同的条件查询
5. **白名单验证的动态查询**
   - 安全实践:对动态字段进行白名单验证
   - 对比:与正例5相同的动态需求
6. **Spring Data JPA安全用法**
   - 安全实践:使用Spring Data Repository的方法推导和@Query安全注解
   - 对比:现代化的安全数据访问方式
## 代码结构规范
### 类级别要求

初始生成结果

rules:
  - id: java-sql-injection
    message: 检测到潜在的SQL注入漏洞
    languages: [java]
    severity: ERROR
    mode: taint
    pattern-sources:
      - pattern: |
          $REQUEST.getParameter(...)
    pattern-sinks:
      - pattern: |
          $STATEMENT.executeQuery(...)

和硬编码密码规则一样,也是需要反复多轮改进,才能得到理想的结果。

1763607660_691e846c4bdb42d54bb2a.png!small?1763607661228

实际执行结果。

1763607672_691e8478656b883ba0f7a.png!small?1763607673327

1763607681_691e8481733127ba50171.png!small?1763607682388

四、AI生成规则实践

4.1 Prompt工程技巧

  1. 具体明确:提供详细的漏洞场景和技术背景

  2. 分步请求:复杂规则可以拆分成多个Prompt

  3. 示例引导:提供输入输出示例,引导AI理解需求

4.2 规则优化策略

  1. 渐进式改进:基于AI的初稿进行迭代优化

  2. 测试驱动:为每个规则编写正例和反例测试用例

  3. 误报分析:分析误报原因,持续改进规则逻辑

五、结语

通过本次实战,演示了如何利用AI辅助生成针对两类漏洞的Java安全规则。这种协作模式显著提升了规则编写的效率,但关键在于安全专家的审核和优化。

六、项目地址

github项目:https://github.com/Binye234/semgrep-demo


文章来源: https://www.freebuf.com/articles/ai-security/458163.html
如有侵权请联系:admin#unsafe.sh