提交 9579fa7c 编写于 作者: martianzhang's avatar martianzhang

add new heuristic rule RES.009

  不建议使用连续判断
  SELECT * FROM tbl WHERE col = col = 'abc'
上级 268d9aee
......@@ -1308,6 +1308,42 @@ func (q *Query4Audit) RuleLoadFile() Rule {
return rule
}
// RuleMultiCompare RES.009
func (q *Query4Audit) RuleMultiCompare() Rule {
var rule = q.RuleOK()
if q.TiStmt != nil {
for _, tiStmt := range q.TiStmt {
switch node := tiStmt.(type) {
case *tidb.SelectStmt:
switch where := node.Where.(type) {
case *tidb.BinaryOperationExpr:
switch where.L.(type) {
case *tidb.BinaryOperationExpr:
rule = HeuristicRules["RES.009"]
}
}
case *tidb.UpdateStmt:
switch where := node.Where.(type) {
case *tidb.BinaryOperationExpr:
switch where.L.(type) {
case *tidb.BinaryOperationExpr:
rule = HeuristicRules["RES.009"]
}
}
case *tidb.DeleteStmt:
switch where := node.Where.(type) {
case *tidb.BinaryOperationExpr:
switch where.L.(type) {
case *tidb.BinaryOperationExpr:
rule = HeuristicRules["RES.009"]
}
}
}
}
}
return rule
}
// RuleStandardINEQ STA.001
func (q *Query4Audit) RuleStandardINEQ() Rule {
var rule = q.RuleOK()
......
......@@ -941,6 +941,46 @@ func TestRuleLoadFile(t *testing.T) {
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
// RES.009
func TestRuleMultiCompare(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
sqls := [][]string{
{
"SELECT * FROM tbl WHERE col = col = 'abc'",
"UPDATE tbl set col = 1 WHERE col = col = 'abc'",
"DELETE FROM tbl WHERE col = col = 'abc'",
},
{
"SELECT * FROM tbl WHERE col = 'abc'",
},
}
for _, sql := range sqls[0] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleMultiCompare()
if rule.Item != "RES.009" {
t.Error("Rule not match:", rule.Item, "Expect : RES.009, SQL: ", sql)
}
} else {
t.Error("sqlparser.Parse Error:", err)
}
}
for _, sql := range sqls[1] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleMultiCompare()
if rule.Item != "OK" {
t.Error("Rule not match:", rule.Item, "Expect : OK, SQL: ", sql)
}
} else {
t.Error("sqlparser.Parse Error:", err)
}
}
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
// STA.001
func TestRuleStandardINEQ(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
......
......@@ -965,6 +965,14 @@ func init() {
Case: "LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;",
Func: (*Query4Audit).RuleLoadFile,
},
"RES.009": {
Item: "RES.009",
Severity: "L2",
Summary: "不建议使用连续判断",
Content: "类似这样的 SELECT * FROM tbl WHERE col = col = 'abc' 语句可能是书写错误,您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。",
Case: "SELECT * FROM tbl WHERE col = col = 'abc'",
Func: (*Query4Audit).RuleMultiCompare,
},
"SEC.001": {
Item: "SEC.001",
Severity: "L0",
......
......@@ -1022,6 +1022,16 @@ select * from tbl where 1 = 1;
```sql
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
```
## 不建议使用连续判断
* **Item**:RES.009
* **Severity**:L2
* **Content**:类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误,您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。
* **Case**:
```sql
SELECT * FROM tbl WHERE col = col = 'abc'
```
## 请谨慎使用TRUNCATE操作
* **Item**:SEC.001
......
......@@ -97,6 +97,7 @@ advisor.Rule{Item:"RES.005", Severity:"L4", Summary:"UPDATE 语句可能存在
advisor.Rule{Item:"RES.006", Severity:"L4", Summary:"永远不真的比较条件", Content:"查询条件永远非真,如果该条件出现在 where 中可能导致查询无匹配到的结果。", Case:"select * from tbl where 1 != 1;", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"RES.007", Severity:"L4", Summary:"永远为真的比较条件", Content:"查询条件永远为真,可能导致 WHERE 条件失效进行全表查询。", Case:"select * from tbl where 1 = 1;", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"RES.008", Severity:"L2", Summary:"不建议使用LOAD DATA/SELECT ... INTO OUTFILE", Content:"SELECT INTO OUTFILE 需要授予 FILE 权限,这通过会引入安全问题。LOAD DATA 虽然可以提高数据导入速度,但同时也可能导致从库同步延迟过大。", Case:"LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"RES.009", Severity:"L2", Summary:"不建议使用连续判断", Content:"类似这样的 SELECT * FROM tbl WHERE col = col = 'abc' 语句可能是书写错误,您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。", Case:"SELECT * FROM tbl WHERE col = col = 'abc'", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"SEC.001", Severity:"L0", Summary:"请谨慎使用TRUNCATE操作", Content:"一般来说想清空一张表最快速的做法就是使用TRUNCATE TABLE tbl_name;语句。但TRUNCATE操作也并非是毫无代价的,TRUNCATE TABLE无法返回被删除的准确行数,如果需要返回被删除的行数建议使用DELETE语法。TRUNCATE 操作还会重置 AUTO_INCREMENT,如果不想重置该值建议使用 DELETE FROM tbl_name WHERE 1;替代。TRUNCATE 操作会对数据字典添加源数据锁(MDL),当一次需要 TRUNCATE 很多表时会影响整个实例的所有请求,因此如果要 TRUNCATE 多个表建议用 DROP+CREATE 的方式以减少锁时长。", Case:"TRUNCATE TABLE tbl_name", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"SEC.002", Severity:"L0", Summary:"不使用明文存储密码", Content:"使用明文存储密码或者使用明文在网络上传递密码都是不安全的。如果攻击者能够截获您用来插入密码的SQL语句,他们就能直接读到密码。另外,将用户输入的字符串以明文的形式插入到纯SQL语句中,也会让攻击者发现它。如果您能够读取密码,黑客也可以。解决方案是使用单向哈希函数对原始密码进行加密编码。哈希是指将输入字符串转化成另一个新的、不可识别的字符串的函数。对密码加密表达式加点随机串来防御“字典攻击”。不要将明文密码输入到SQL查询语句中。在应用程序代码中计算哈希串,只在SQL查询中使用哈希串。", Case:"create table test(id int,name varchar(20) not null,password varchar(200)not null)", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"SEC.003", Severity:"L0", Summary:"使用DELETE/DROP/TRUNCATE等操作时注意备份", Content:"在执行高危操作之前对数据进行备份是十分有必要的。", Case:"delete from table where col = 'condition'", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
......
......@@ -1022,6 +1022,16 @@ select * from tbl where 1 = 1;
```sql
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
```
## 不建议使用连续判断
* **Item**:RES.009
* **Severity**:L2
* **Content**:类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误,您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。
* **Case**:
```sql
SELECT * FROM tbl WHERE col = col = 'abc'
```
## 请谨慎使用TRUNCATE操作
* **Item**:SEC.001
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册