如何使查询构建器安全并防止sql注入

这是我的代码:


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。但是,它返回所有数据。


如何提高安全性?


慕哥6287543
浏览 139回答 1
1回答

梦里花落0921

实施@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...)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go