Поддержка неэмулируемых подготовленных операторов из MS SQL Server через PHP в Linux

php sql-server linux pdo freetds

585 просмотра

1 ответ

838 Репутация автора

Резюме

Я пытаюсь использовать подготовленные операторы для остановки SQL-инъекций, но не могу найти поддержку, которая мне нужна, чтобы гарантировать правильную работу.


сценарий

Я размещаю сайт на Linux, который подключается к Microsoft SQL Server с FreeTDS версии 0.91, в частности, с использованием FreeTDS dblib. Я установил tdsверсию 7.4 для подключения к базе данных и использую объект PDO PHP .

Согласно документации FreeTDS , 4.2 не поддерживает подготовленные заявления:

TDS 4.2 имеет ограничения

  • Только ASCII, конечно.
  • RPC не поддерживается.
  • BCP не поддерживается.
  • поля varchar ограничены 255 символами. Если ваша таблица определяет более длинные поля, они будут усечены.
  • динамические запросы (также называемые подготовленными операторами) не поддерживаются.

Однако ничто не указывает на то, что 7.4 не поддерживает подготовленные операторы, что дает мне разумную уверенность, что они, по крайней мере, не вызовут ошибку драйвера.

PDO PHP поддерживает определенные атрибуты соединения через PDO::setAttribute(). Я заинтересован в том, PDO::ATTR_ERRMODEчтобы установить все ошибки как исключения и PDO::ATTR_EMULATE_PREPARESзаставить базу данных делать подготовленные операторы, если они совместимы.


вопрос

При тестировании соединения я получаю следующую ошибку:

Ошибка базы данных: SQLSTATE [IM001]: драйвер не поддерживает эту функцию: драйвер не поддерживает настройку атрибутов

Не имея возможности установить PDO::ATTR_EMULATE_PREPARES, я не могу гарантировать, что база данных фактически выполняет подготовленные операторы, как и предполагалось.

Есть ли способ изменить мой подход или есть альтернативный подход, чтобы гарантировать безопасное выполнение подготовленных операторов на MS SQL Server из Linux?

Автор: Stewart Smith Источник Размещён: 12.07.2016 08:46

Ответы (1)


1 плюс

838 Репутация автора

Решение

Решение

Используйте ODBCвместо dblib, который обеспечивает полную функциональность PDO. Обратите внимание, что существует две возможные конфигурации ODBC: автономный ODBC и FreeTDS с драйвером ODBC . По моему опыту, чтобы установить набор символов для соединения, это должно быть сделано через FreeTDS с использованием драйвера ODBC, что делает объединенную конфигурацию предпочтительной.


Настройка ODBC

Я просмотрел множество различных публикаций StackOverflow и различные источники документации в Интернете о том, как правильно установить ODBC. Я вытащил свое решение из смеси следующих трех ссылок:

Ниже приведен список шагов , которые я использовал для настройки ODBCиспользования FreeTDSна системе на основе Debian.

TDS 8.0 поддерживает подготовленные заявления.

ПРИМЕЧАНИЕ: не будет поддерживать SET NAMES aили SET CHARSET aна соединение; наборы символов должны быть определены с использованием комбинированной конфигурации путем установки атрибута FreeTDS. При использовании автономного драйвера ODBC по умолчанию использовалась кодировка ASCII, что дало странные результаты. Смотрите мой другой пост для примеров возможных проблем.

Установите требуемые пакеты:

sudo apt-get установить freetds-bin freetds-common unixodbc tdsodbc php5-odbc

  • freetds-binпредоставляет FreeTDS, а также tsqlи isql(используется для отладки позже).
  • freetds-commonбыл уже установлен в системе, но не включает два средства отладки. Установка freetds-binпозже после определения конфигурации не вызывает проблем.
  • unixodbc это драйвер ODBC
  • tdsodbc предоставляет протокол TDS для ODBC
  • php5-odbcмодуль php для используемых драйверов ODBC Обратите внимание, что ваша версия php может отличаться от моей.

Настроить автономный unixODBC

Настройки драйвера ODBC в /etc/odbcinst.ini:

[odbc]
Description     = ODBC driver
Driver          = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup           = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so 
UsageCount      = 1

Создайте общесистемную конфигурацию имени источника данных в /etc/odbc.ini:

[datasourcename]
 Driver         = odbc
 Description    = Standalone ODBC
 Server         = <IP or hostname>
 Port           = <port>
 TDS_Version    = 8.0

Настройте unixODBC и FreeTDS:

Настройки драйвера ODBC в /etc/odbcinst.ini:

[odbc]
Description     = ODBC driver
Driver          = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup           = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so 
UsageCount      = 1

Создайте общесистемную конфигурацию имени источника данных в /etc/odbc.ini:

[datasourcename]
Driver          = FreeTDS_odbc
Description     = Uses FreeTDS configuration settings defined in /etc/freetds/freetds.conf
Servername      = datasourcename
TDS_Version     = 8.0

Добавьте конфигурацию имени источника данных ODBC в FreeTDS в /etc/freetds/freetds.conf:

[datasourcename]
    host = <IP or hostname>
    port = <port>
    client charset = UTF-8
    tds version = 8.0
    text size = 20971520
    encryption = required

ВАЖНО: убедитесь, что файлы odbc доступны для чтения процессом, который их читает. Если вы используете свой веб-сервер, используя www-dataпользователя, у него должны быть соответствующие разрешения для чтения этих файлов!

Теперь вы можете установить набор символов freetds.confподключения и подключиться к базе данных с помощью PDO как

$pdo = new PDO('odbc:datasourcename');

Тестирование:

Используйте tsqlдля проверки того, что FreeTDS настроен и может подключаться к базе данных.

tsql -S имя источника данных -U имя пользователя -P пароль

Используйте isqlдля проверки правильности подключения ODBC.

isql -v datasourcename имя пользователя пароль

Связать ODBC с PHP:

Добавьте модуль ODBC PHP php.ini, добавив следующее:

extension = odbc.so

Обратите внимание, что ваше php.iniместоположение будет зависеть от того, какой веб-сервер вы используете. Используйте <?php phpinfo(); ?>и просмотрите его через веб-сервер, чтобы найти его местоположение.

Перезапустите Apache

РЕДАКТИРОВАТЬ: Добавлена ​​информация о возможностях набора символов драйвера, так как я столкнулся с проблемами с автономной конфигурацией ODBC, где он игнорировал бы любую попытку изменить набор символов соединения.

Автор: Stewart Smith Размещён: 13.07.2016 09:02
Вопросы из категории :
32x32