Как переопределить санацию SQL в ColdFusion - PullRequest
5 голосов
/ 02 июня 2009

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

Я столкнулся с проблемой, потому что 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 

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

Ответы [ 3 ]

17 голосов
/ 02 июня 2009

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

SELECT #Arguments.strSelectAttributes#

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

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

SELECT #PreserveSingleQuotes(Arguments.strSelectAttributes)#

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

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

SELECT #LCase(Arguments.strSelectAttributes)#

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

7 голосов
/ 02 июня 2009

Поместите вызов preserveSingleQuotes () вокруг вашей переменной. Это сделано специально для написания динамического 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>
0 голосов
/ 17 июля 2009

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

...