Есть ли что-то еще, что код должен делать для очистки идентификаторов (таблица, представление, столбец), кроме как заключать их в двойные кавычки и "удваивать" двойные кавычки, присутствующие в имени идентификатора? Ссылки будут оценены.
Я унаследовал кодовую базу с системой пользовательского объектно-реляционного отображения (ORM). SQL не может быть записан в приложении, но ORM должен в конечном итоге генерировать SQL для отправки на SQL Server. Все идентификаторы заключены в двойные кавычки.
string QuoteName(string identifier)
{
return "\"" + identifier.Replace("\"", "\"\"") + "\"";
}
Если бы я строил этот динамический SQL в SQL , я бы использовал встроенную функцию SQL Server QUOTENAME:
declare @identifier nvarchar(128);
set @identifier = N'Client"; DROP TABLE [dbo].Client; --';
declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = QUOTENAME(@identifier, '"');
print @delimitedIdentifier;
-- "Client""; DROP TABLE [dbo].Client; --"
Я не нашел какой-либо определенной документации о том, как избежать кавычек идентификаторов в SQL Server. Я нашел Идентификаторы с разделителями (компонент Database Engine) и также увидел этот вопрос о потоке стека о очистке.
Если бы пришлось вызывать функцию QUOTENAME, чтобы просто заключить в кавычки идентификаторы, которые являются большим трафиком для SQL Server, который не требуется.
ORM, кажется, довольно хорошо продуман в отношении SQL-инъекций. Он находится на C # и предшествует порту nHibernate, Entity Framework и т. Д. Весь пользовательский ввод отправляется с использованием объектов ADO.NET SqlParameter, это просто имена идентификаторов, которые меня беспокоят в этом вопросе. Это должно работать на SQL Server 2005 и 2008.
Обновление от 2010-03-31
Хотя приложение не должно разрешать ввод пользователя для имен идентификаторов в запросах, ORM делает это с помощью синтаксиса запроса, который используется как для чтения в стиле ORM, так и для пользовательских запросов. Это ORM, который я пытаюсь в конечном итоге предотвратить всеми возможными атаками SQL-инъекций, поскольку это очень мало и легко проверить в отличие от всего кода приложения.
Простой пример интерфейса запроса:
session.Query(new TableReference("Client")
.Restrict(new FieldReference("city") == "Springfield")
.DropAllBut(new FieldReference("first_name"));
ADO.NET отправляет запрос:
exec sp_executesql N'SELECT "T1"."first_name"
FROM "dbo"."Client" AS "T1"
WHERE "T1"."city" = @p1;',
N'@p1 nvarchar(30)',
N'Springfield';
Возможно, было бы полезно подумать о том, как это может выглядеть в nHibernate Query Language (HQL):
using (ISession session = NHibernateHelper.OpenSession())
{
Client client = session
.CreateCriteria(typeof(Client)) \\ <-- TableReference in example above
.Add(Restrictions.Eq("city", "Springfield")) \\ <-- FieldReference above
.UniqueResult<Client>();
return client;
}
Может быть, я должен посмотреть и посмотреть, как nHibernate защищает ввод.