Как переопределить очистку SQL в ColdFusion

У меня есть неудачная задача очистить кучу старого кода ColdFusion. Запросы поступают повсюду, я работаю над тем, чтобы перенести их все на обычные CFC для облегчения обслуживания.

У меня возникла проблема, потому что cfquery автоматически преобразует одинарные кавычки в двойные одинарные кавычки. Как я могу переопределить это поведение?

Более конкретная информация приведена ниже.


Итак, вот запрос, с которого я начал:

<cfquery name="getObjectInfo" datasource="#BaseDS#">
  SELECT groupName AS lastname, '[Group]' AS firstname
  FROM   groups
  WHERE  groups.group_id = #objectreference_id#
</cfquery>

Странно то, что литерал «выбирается» из-за того, как мы хотим, чтобы он отображался (опять же, я не писал это, я просто пытаюсь немного почистить). Итак, в общей функции есть необязательный параметр для предложения select:

  <cffunction name="fSelGroup" access="public" returntype="query"
              hint="Returns query selecting given group.">

    <cfargument name="intGroupID" type="numeric" required="true"
                hint="ID of group to be returned." />
    <cfargument name="strSelectAttributes" type="string" required="false"
                hint="Attributes to be selected in query"
                default="*" />

    <cfquery name="getObjectInfo" datasource="#Application.DataSource#">
      SELECT #Arguments.strSelectAttributes#
      FROM   Groups
      WHERE  Group_ID = #Arguments.intGroupID#
    </cfquery>

    <cfreturn getObjectInfo />

  </cffunction>

Вот проблема: когда я передаю "GroupName AS LastName, '[Group]' AS FirstName" для параметра strSelectAttributes, в базу данных отправляется следующий запрос:

SELECT GroupName AS LastName, ''[Group]'' AS FirstName
FROM   Groups
WHERE  Group_ID = 4 

Видите ли, мои кавычки были "дезинфицированы" в недопустимый запрос.


person Kip    schedule 02.06.2009    source источник
comment
См. также stackoverflow.com/questions/266586/   -  person ale    schedule 02.06.2009


Ответы (3)


ColdFusion не экранирует все одинарные кавычки, а только те, которые появляются в запросе посредством интерполяции переменных. Это нарушитель:

SELECT #Arguments.strSelectAttributes#

Обычно это полезная вещь и небольшая линия защиты от атак SQL-инъекций. Итак, правило номер один (здесь и везде): не создавайте свою строку SQL из переменных.

Если вы обязательно используете переменные для построения строки SQL, несмотря на все возможные негативные последствия, используйте функцию PreserveSingleQuotes():

SELECT #PreserveSingleQuotes(Arguments.strSelectAttributes)#

Эта функция не позволяет ColdFusion автоматически экранировать одинарные кавычки.

Кстати, любой другой вызов функции делает то же самое. Пытаться:

SELECT #LCase(Arguments.strSelectAttributes)#

это означает, что PreserveSingleQuotes() на самом деле является просто функцией без операции, которая превращает строку в результат функции, предотвращая выполнение процедуры автоматической интерполяции переменных.

person Tomalak    schedule 02.06.2009

Поместите вызов saveSingleQuotes() вокруг вашей переменной. Он создан специально для написания динамического SQL. Кроме того, вам действительно следует использовать cfqueryparam для ваших значений, и я надеюсь, что вы каким-то образом очищаете свой ввод, чтобы arguments.strSelectAttributes не мог содержать что-то вроде ';drop table groups; в этом.

<cfquery name="getObjectInfo" datasource="#Application.DataSource#">
  SELECT #preserveSingleQuotes(Arguments.strSelectAttributes)#
  FROM   Groups
  WHERE  Group_ID = <cfqueryparam value="#Arguments.intGroupID#" cfsqltype="cf_sql_integer"/>
</cfquery>
person Nathan Strutz    schedule 02.06.2009
comment
благодаря. я знаю о внедрении sql, но в моем случае параметр исходит только из кода, которым мы управляем, а не от пользователя. - person Kip; 02.06.2009
comment
Я бы не стал использовать его только в коде, который мы контролируем, в качестве оправдания для написания класса DAO, который в противном случае уязвим для SQL-инъекций. - person Licky Lindsay; 02.06.2009
comment
SQL-инъекция — не единственная причина использования параметров привязки запроса. Это также позволяет вашей БД предварительно скомпилировать запрос, что ускоряет его работу. - person Nathan Strutz; 03.06.2009

Если вы действительно хотите очистить код, второй шаг — преобразовать эти спагетти в хранимые процедуры.

person Community    schedule 17.07.2009