Мне было дано задание переписать старый веб-API.
Этот API-интерфейс считывает запросы SQL из базы данных.
В буквальном смысле есть представление "Запросы" в имени, которое содержит "SqlText "column.
SELECT SqlText FROM Queries WHERE QueryID = 123
" SqlText "содержит только простые SQL-запросы в формате SELECT [columns] FROM [table]
по соглашению.
Запрос изменяется в зависимости от параметров URL-адреса в запросе.Результат этого запроса затем отображается как результат.
string parsedColumns = ParseColumns(queryRow); //contains "Column1, Column2";
string parsedTable = ParseTable(queryRow); //contains "SomeTable"
string requestColumns = HttpContext.Request["columns"];
string sqlColumns = requestColumns ?? parsedColumns;
string col1Condition = HttpContext.Request["Column1"]
string col2Condition = HttpContext.Request["Column2"]
string sqlQuery = "SELECT " + sqlColumns
+ " FROM " + parsedTable
+ " WHERE Column1 = " + col1Condition
+ " AND Column2 = " + col2Condition;
Это очевидная проблема внедрения SQL, поэтому я начал переписывать его.
Теперь есть еще три проблемы.
- Я не могу изменить структуру базы данных или соглашение
- База данных - Oracle или SQL Server
- Я не знаю, как правильно работать с URL-адресом столбцовпараметр, чтобы избежать внедрения SQL.
Параметры URL в предложении WHERE легко преобразовать в параметры SQL как для SQL Server, так и для Oracle.
SQL Server
var sqlCommand = new SqlCommand("SELECT * FROM SomeTable WHERE Condition1 = @con1 AND Condition2 = @con2");
Oracle
var oracleCommand = new OracleCommand("SELECT * FROM SomeTable WHERE Condition1 = :con1 AND Condition2 = :con2");
Идентификаторы столбцов
Проблема с HttpContext.Request["columns"]
.Мне все еще нужно как-то изменить строку SQL-запроса с параметрами URL, которые мне совсем не нравятся.
Чтобы упростить проблему, давайте рассмотрим один столбец из запроса URL.
string column = HttpContext.Request["column"];
var cmd = new SqlCommand($"SELECT {column} FROM ...");
Я знаю, что в SQL Server идентификатор может быть заключен в фигурные скобки.Поэтому я считаю, что я в безопасности, если уберу все скобки со столбца.
string column = HttpContext.Request["column"];
column = column.Replace("[", "").Replace("]", "");
column = $"[{column}]";
var cmd = new SqlCommand($"SELECT {column} FROM ...");
Oracle использует кавычки.
string column = HttpContext.Request["column"];
column = column.Replace("\"", "");
column = $"\"{column}\"";
var cmd = new OracleCommand($"SELECT {column} FROM ...");
Вопрос
- Достаточно ли безопасен этот sql-впрыск?
- Или этот вариант использования по своей сути небезопасен для sql-впрыска?