如何使用groovy防止sql注入?

如何使用groovy防止sql注入?,groovy,sql-injection,Groovy,Sql Injection,我有一个类似于: String sql = """SELECT id, name, sex, age, bron_year, address, phone, state, comment, is_hbp, is_dm, is_cva, is_copd, is_chd, is_cancer, is_floating, is_poor, is_disability, is_mental FROM statistics_stin WHERE 1=1 ${p.team_num == 0 ? "" :

我有一个类似于:

String sql = """SELECT id, name, sex, age, bron_year, address, phone, state, comment, is_hbp, is_dm, is_cva, is_copd, is_chd, is_cancer, is_floating, is_poor, is_disability, is_mental
 FROM statistics_stin WHERE 1=1
 ${p.team_num == 0 ? "" : "AND team_num = ${p.team_num}"}
 ${p.zone == 0 ? "" : "AND team_id = ${p.zone}"}
 ${p.is_hbp == 2 ? "" : "AND is_hbp = ${p.is_hbp}"}
 ${p.is_dm == 2 ? "" : "AND is_dm = ${p.is_dm}"}
 ${p.is_chd == 2 ? "" : "AND is_chd = ${p.is_chd}"}
 ${p.is_cva == 2 ? "" : "AND is_cva = ${p.is_cva}"}
 ${p.is_copd == 2 ? "" : "AND is_copd = ${p.is_copd}"}
 ${p.is_cancer == 2 ? "" : "AND is_cancer = ${p.is_cancer}"}
 ${p.is_floating == 2 ? "" : "AND is_floating = ${p.is_floating}"}
 ${p.is_poor == 2 ? "" : "AND is_poor = ${p.is_poor}"}
 ${p.is_disability == 2 ? "" : "AND is_disability = ${p.is_disability}"}
 ${p.is_mental == 2 ? "" : "AND is_mental = ${p.is_mental}"}
 ${p.is_aged == 2 ? "" : (p.is_aged == 1 ? " AND age >= 65" : " AND age < 65")}
 ${p.is_prep_aged == 2 ? "" : (p.is_prep_aged == 1 ? "AND (age BETWEEN 60 AND 64)" : "AND (age < 60 OR age > 64)")}
 ${p.is_young == 2 ? "" : (p.is_young == 1 ? " AND age < 60" : " AND age >= 60")}
 ORDER BY team_id ASC, id ASC
 LIMIT ${start}, ${page_size}
 """;
这里p是一个json对象,类似于:

p = {is_aged=2, is_cancer=2, is_chd=1, is_copd=2, is_cva=2, is_disability=2, is_dm=2, is_floating=2, is_hbp=1, is_mental=2, is_poor=2, pn=1, team_num=0, zone=0}
这种方式有sql注入。我知道我可以使用params类型,如:

executer.rows('SELECT * from statistics_stin WHERE is_chd=:is_chd', [is_chd: 1]);
但这种情况有很多限制和条件,使用与否将由json p决定


如何执行此操作?

您遇到了动态SQL绑定的问题,即绑定参数的数量不是恒定的,而是取决于输入

有一个优雅的解决方案 它在Groovy中有更优雅的实现

基本思想是简单绑定所有变量,具有输入值且应使用的变量正常处理,例如

 col1 = :col1
没有输入(且应忽略)的变量与虚拟结构绑定:

 (1=1 or :col2 is NULL)
i、 e.快捷方式评估有效地忽略了它们

下面是三列的两个示例

 def p = ["col1" : 1, "col2" : 2, "col3" : 3]
这个输入导致一个完整的查询

SELECT col1, col2, col3
 FROM tab WHERE
 col1 = :col1 AND
 col2 = :col2 AND
 col3 = :col3
ORDER by col1,col2,col3
有限的投入

 p = [ "col3" : 3] 
你得到这个查询

SELECT col1, col2, col3
 FROM tab WHERE
 (1=1 or :col1 is NULL) AND
 (1=1 or :col2 is NULL) AND
 col3 = :col3
ORDER by col1,col2,col3
下面是Groovy创建SQL语句的过程

String sql = """SELECT col1, col2, col3
 FROM tab WHERE   
 ${(!p.col1) ? "(1=1 or :col1 is NULL)" : "col1 = :col1"} AND
 ${(!p.col2) ? "(1=1 or :col2 is NULL)" : "col2 = :col2"} AND
 ${(!p.col3) ? "(1=1 or :col3 is NULL)" : "col3 = :col3"}  
ORDER by col1,col2,col3
""" 

您甚至可以去掉丑陋的
1=1
谓词;)

另一个选项是在构建查询时构建绑定,然后执行
行的适当实现

def query = new StringBuilder( "SELECT id, name, sex, age, bron_year, address, phone, state, comment, is_hbp, is_dm, is_cva, is_copd, is_chd, is_cancer, is_floating, is_poor, is_disability, is_mental FROM statistics_stin WHERE 1=1" )
def binds = []
if ( p.team_num == 0 ) {
    query.append( ' AND team_num = ? ' )
    binds << p.team_num
}
if ( p.zone == 0 ) {
    query.append( ' AND team_id = ? ' )
    binds << p.zone == 0
}
...
executer.rows(query.toString(), binds);
def query=new StringBuilder(“选择id、姓名、性别、年龄、布朗年、地址、电话、州、评论、is_hbp、is_dm、is_cva、is_copd、is_chd、is_癌症、is_浮动、is_贫穷、is_残疾、is_精神统计数据,其中1=1”)
def绑定=[]
如果(p.team_num==0){
query.append('AND team_num=?'))

binds@meters谢谢,但我不认为它能阻止sql注入。谢谢。通过这种方式,它可以工作,即使sql不清楚。构建绑定数组的不错选择。
def query = new StringBuilder( "SELECT id, name, sex, age, bron_year, address, phone, state, comment, is_hbp, is_dm, is_cva, is_copd, is_chd, is_cancer, is_floating, is_poor, is_disability, is_mental FROM statistics_stin WHERE 1=1" )
def binds = []
if ( p.team_num == 0 ) {
    query.append( ' AND team_num = ? ' )
    binds << p.team_num
}
if ( p.zone == 0 ) {
    query.append( ' AND team_id = ? ' )
    binds << p.zone == 0
}
...
executer.rows(query.toString(), binds);