使用Spring Data Couchbase @Query注解时如何防范SQL注入及参数转义?
解决Spring Data Couchbase自定义查询中参数含转义双引号的问题
问题分析
当前通过@Query编写N1QL查询时,直接将#{#name}嵌入字符串引号内,当参数包含转义双引号(如"test\"name")时,会破坏N1QL语法结构,导致查询失效,同时存在注入风险。
解决方案:使用OWASP ESAPI库净化参数
1. 引入OWASP ESAPI依赖
Maven项目在pom.xml中添加:
<dependency> <groupId>org.owasp.esapi</groupId> <artifactId>esapi</artifactId> <version>2.5.2.0</version> </dependency>
Gradle项目在build.gradle中添加:
implementation 'org.owasp.esapi:esapi:2.5.2.0'
2. 两种参数净化实现方式
方式一:Service层预处理参数
在调用Repository前完成参数净化,再传递给查询方法:
import org.owasp.esapi.ESAPI; import org.owasp.esapi.Encoder; @Service public class YourService { private final YourRepository repository; private final Encoder encoder = ESAPI.encoder(); public YourService(YourRepository repository) { this.repository = repository; } public List<YourEntity> findByName(String name) { // 净化字符串,自动处理转义双引号等特殊字符 String sanitizedName = encoder.encodeForSQL(name); return repository.findByName(sanitizedName); } }
Repository层改用命名参数绑定(无需手动加引号):
@Repository public interface YourRepository extends CouchbaseRepository<YourEntity, String> { @Query(""" #{n1ql.selectEntity} WHERE #{n1ql.filter} AND name = $1 AND … """) List<YourEntity> findByName(String sanitizedName); }
方式二:Repository层通过SpEL直接调用ESAPI
在@Query的SpEL表达式中直接调用ESAPI静态方法,无需Service层额外处理:
@Repository public interface YourRepository extends CouchbaseRepository<YourEntity, String> { @Query(""" #{n1ql.selectEntity} WHERE #{n1ql.filter} AND name = "#{T(org.owasp.esapi.ESAPI).encoder().encodeForSQL(#name)}" AND … """) List<YourEntity> findByName(@Param("name") String name); }
关键说明
- OWASP ESAPI的
encodeForSQL方法适配N1QL的字符串转义规则,能自动处理双引号、单引号等特殊字符,保证查询语法正确。 - 优先使用命名参数绑定或SpEL结合ESAPI的方式,避免手动拼接字符串,从根源避免语法错误和注入风险。
- 测试时需覆盖含特殊字符的场景(如
"test\"name"、'test'name),验证查询有效性。
内容的提问来源于stack exchange,提问作者axnet
相关产品推荐
相关产品推荐

