Динамический запрос для использования с платформой go-gorm - PullRequest
0 голосов
/ 17 января 2019

Я пишу динамический запрос и выполняю его с помощью функции go-gorm db.Raw (). Я хочу предотвратить атаки SQL-инъекций на построенный мной запрос.

Я пишу этот запрос, чтобы получить всех пользователей с пагинацией на стороне сервера, поиском и фильтром. Мой запрос работает очень хорошо, но есть угроза атаки SQL Injection.

// GetUserGridDataWithPagination - gets data to show in users grid to admin with pagination
func (controller Admin) GetUserGridDataWithPagination(
    filterBy string,
    searchBy string,
    sortBy string,
    sortOrder string,
    pageSize uint16,
    pageNumber uint16,
) ([]model.AdminUserGridData, int64, uint16, error) {
    var list []model.AdminUserGridData
    query := `SELECT * FROM users_master`
    query1 := `SELECT count(*) FROM users_master`
    clause := ` WHERE `
    filterCondition := ""
    searchCondition := ""
    sortCondition := ""
    if filterBy != "all" {
        filterCondition = ` WHERE role = '` + filterBy + `'`
        clause = ` AND `
    }
    if searchBy != "" {
        search := "'%" + searchBy + "%'"
        searchCondition = clause +
            `name ilike ` + search + ` OR
                email ilike ` + search + ` OR
                phone ilike ` + search + ` OR
                profession ilike ` + search + ` OR
                role ilike ` + search + ` OR
                kyc_status ilike ` + search
    }
    if sortBy != "" {
        column := ""
        if sortBy == "kycStatus" {
            column = "kyc_status"
        } else {
            column = sortBy
        }
        if sortOrder != "" {
            sortCondition = ` ORDER BY ` + column + ` ` + sortOrder
        }
    }
    if filterCondition != "" {
        query = query + filterCondition
        query1 = query1 + filterCondition
    }
    if searchCondition != "" {
        query = query + searchCondition
        query1 = query1 + searchCondition
    }
    if sortCondition != "" {
        query = query + sortCondition
    }
    query = query + ` LIMIT ? OFFSET ?`
    // fetch records from database
    if err := controller.database.Raw(query, pageSize, (pageSize * (pageNumber - 1))).Scan(&list).Error; err != nil {
        log.Error(err)
        return nil, 0, 0, errors.New("Error while processing your request")
    }
    // fetch total no of records from database
    type RowCount struct {
        Count int64 `json:"count"`
    }
    var rowCount RowCount
    if err := controller.database.Raw(query1).Scan(&rowCount).Error; err != nil {
        log.Error(err)
        return nil, 0, 0, errors.New("Error while processing 
your request")
    }
    return list, rowCount.Count, pageNumber, nil
}

Я делал это много раз в своем проекте. Итак, я нахожу способ исправить это, не изменяя запрос, но используя любую стороннюю библиотеку, чтобы исправить это. (как мы делаем в nodejs, используя sql-escape-string пакет доступен в нпм)

1 Ответ

0 голосов
/ 17 января 2019

Вы должны использовать конструктор запросов gorm и передавать параметры в аргументах: Where(query interface{}, args ...interface{}) *DB. Этого будет достаточно. Так как вышеописанные методы gorm изменяют внутреннее состояние создаваемого вами SQL-запроса, можно написать код, подобный следующему:

var usersMasterList []UsersMaster // gorm Model
if filterBy != "all" {
    controller.database.Where("role = ?", filterBy)
}
if searchBy != "" {
    controller.database.Or("name ilike ?", search)
    controller.database.Or("email ilike ?", search)
    //...
}
//...
controller.database.Find(&usersMasterList)

Код не проверен. Вы можете прочитать больше здесь: http://gorm.io/docs/query.html

Или вы можете просто отфильтровать не алфавитно-цифровые символы из этих строк с помощью регулярного выражения:

rx := regexp.MustCompile("[^a-zA-Z0-9]+")
yourString = rx.ReplaceAllString(yourString, "")

Настоятельно рекомендуем переписать ваш код как можно скорее, код будет более безопасным и читабельным.

...