这是我的代码:type mysqlRepository struct { Conn *sql.DB}func (dbconn *mysqlRepository) GetAll(param map[string]string) (response []models.Subject, err error) { var result models.Subject c := 0 q := ` SELECT id, name, teacher, uuid FROM subject ` for i, x := range param { if x != "" { if c > 0 { q += ` AND ` + i + ` = ` + x } else { q += ` WHERE ` + i + ` = ` + x } c++ } } query, err := dbconn.Conn.Query(q) if err != nil { utils.QueryErrorException(err) return } defer query.Close() for query.Next() { errorScanningDataHistory := query.Scan( &result.ID, &result.Name, &result.Teacher, &result.UUID, ) utils.QueryErrorException(errorScanningDataHistory) response = append(response, result) } return}我尝试像这样使用邮递员并运行良好:http://localhost/public/api/v1/subject?name=robert。它只显示罗伯特作为老师的主题但是,如果我注入sql命令,它也可以工作:http://localhost/public/api/v1/subject?name=robert OR 1 = 1。但是,它返回所有数据。如何提高安全性?
1 回答

梦里花落0921
TA贡献1772条经验 获得超6个赞
实施@mkopriva的评论
通过已知/允许列的映射筛选 i。不要连接 x,而是使用占位符 ?并将 x 附加到参数片中,然后将其传递给查询
safeFields := map[string]bool{"name": true}
args := []interface{}{}
where := "WHERE 1"
for i, x := range param {
if _, ok := safeFields[i]; ok && x != "" {
where += fmt.Sprintf(" AND %s=?", i)
args = append(args, x)
}
}
query, err := dbconn.Conn.Query(q+where, args...)
- 1 回答
- 0 关注
- 138 浏览
添加回答
举报
0/150
提交
取消