Параметр FromSqlRaw из списка <String>, безопасный от sql инъекции - PullRequest
3 голосов
/ 15 января 2020

У меня проблема с выполнением необработанного запроса с использованием ядра 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 Ответ

2 голосов
/ 15 января 2020

Это определенно проблема 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")]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...