IQueryable поставщик LINQ и SQL-инъекция? - PullRequest
2 голосов
/ 19 сентября 2011

Я работаю над поставщиком LINQ, который использует IQ Toolkit для перевода запросов LINQ в запросы SQL. Безопасны ли классы, предоставляемые IQ Toolkit, от атак SQL-инъекций? Если нет, то что мне нужно сделать для защиты от атак SQL-инъекций, предположив, что я использую IQ Toolkit и реализую свой собственный поставщик LINQ. Я прочитал LINQ to SQL использует SqlParameter , но мне все еще не ясно, что нужно сделать с SqlParameter для защиты от SQL-инъекций.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Из блога post похоже, что инструментарий IQ (или начальная версия инструментария) не защищен от атак SQL-инъекций. Но вы можете проверить это самостоятельно - выполните запрос, перехватите сгенерированный SQL и посмотрите, есть ли используемые параметры.

1 голос
/ 19 сентября 2011

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

Но вы заинтересованы в защите вашей базы данных от внедрения SQL. Так что, если вы посмотрите на пример кода на этой странице и методе VisitConstant, это место, где вы сталкиваетесь с константами типа значения (string, int и т. Д.) Или IQueryable.

Защита от SQL-инъекций не сложна, вы просто создаете новый SQLParameter или вызываете метод DbProviderFactory.CreateParameter, описанный здесь . Вам понадобится некоторая коллекция для хранения ваших параметров во время обхода дерева выражений. Таким образом, модифицированный код будет выглядеть так:

protected override Expression VisitConstant(ConstantExpression c) {
    IQueryable q = c.Value as IQueryable;
    if (q != null) {
        // assume constant nodes w/ IQueryables are table references
        sb.Append("SELECT * FROM ");
        sb.Append(q.ElementType.Name);
    }
    else if (c.Value == null) {
        sb.Append("NULL");
    }
    else {
        switch (Type.GetTypeCode(c.Value.GetType())) {
            case TypeCode.Boolean:
                param = dbProvider.CreateParameter();
                param.Name = "@param" + paramsList.Count;
                param.Value = (((bool)c.Value) ? 1 : 0;
                paramsList.Add(param);
                sb.Append(param.Name);
                break;
            case TypeCode.String:
                param = dbProvider.CreateParameter();
                param.Name = "@param" + paramsList.Count;
                param.Value = c.Value; // you don't have to care about escaping or formatting
                paramsList.Add(param);
                sb.Append(param.Name);
                break;
            ...
            case TypeCode.Object:
                throw new NotSupportedException(string.Format("The constant for '{0}' is not supported", c.Value));
            default:
                sb.Append(c.Value);
                break;
        }
    }
    return c;
}

Итак, пока вы просматриваете дерево выражений, вы строите строку SQL и собираете параметры SQL.

...