Параметр FromSqlRaw из List <String>, который защищен от внедрения SQL

У меня возникла проблема, когда мне нужно выполнить необработанный запрос, используя ядро ​​Entity Framework, для которого требуется список строк в качестве параметра для оператора Where IN, и я могу заставить запрос работать, но я беспокоюсь о атаках SQL-инъекций. Мой запрос будет выглядеть примерно так:

    public static string BulkGetColumn3Query
    {
        get 
        {
            return @"
                SELECT Column1, Column2
                FROM TABLE
                WHERE  column3 IN ({0})";
        }
    }

Метод, который вызывает его так, как он есть, теперь выглядит примерно так:

    async Task<List<EntityObject>> GetModelObjectByColumn3(List<string> column3Values)
    {
        var column3ValuesString = string.Join(",", column3Values);
        var query = BulkGetColumn3Query.Replace("{0}", column3ValuesString);

        return await DbSetObject
            .FromSqlRaw(query)
            .AsNoTracking()
            .ToListAsync();
    }

Что я могу сделать, чтобы попытаться смягчить атаки с использованием SQL-инъекций?

Всего 1 ответ


Это наиболее определенно проблема внедрения SQL, потому что column3ValuesString конечном итоге отправляется напрямую в БД.

Замените это параметризованным запросом:

string BulkGetColumn3Query(List<string> column3Values) {
    var selectList = string.Join(", ", column3Values.Select((_, i) => $"@p{i}"));
    return $@"SELECT Column1, Column2
            FROM TABLE
            WHERE  column3 IN ({selectList})";
}

async Task<List<EntityObject>> GetModelObjectByColumn3(List<string> column3Values)
{
   var query = BulkGetColumn3Query(column3Values);
   var sqlParameters = new List<SqlParameter>();
   return await Trailers
        .FromSqlRaw(query, column3Values.Select((val, i) => new SqlParameter($"@p{i}", val)))
        .AsNoTracking()
        .ToListAsync();
}

Допустим, в вашем списке есть три элемента: ["first", "second", "third"] . Тогда ваша строка запроса будет выглядеть так:

SELECT Column1, Column2
FROM TABLE
WHERE column3 IN (@p0, @p1, @p2)

и список параметров будет выглядеть так:

[   new SqlParameter("@p0", "first")
,   new SqlParameter("@p1", "second")
,   new SqlParameter("@p2", "third")]

Поскольку все значения отправляются как параметры, запрос теперь безопасен.