概要
我试图使用预处理语句来停止SQL注入,但无法find我需要的支持,以确保它正常工作。
脚本
我正在Linux上托pipe一个站点,它使用FreeTDS版本0.91连接到Microsoft SQL Server,特别是使用FreeTDS的dblib
。 我已经将数据库连接的tds
版本设置为7.4,并使用PHP的PDO对象。
根据FreeTDS文档 ,4.2不支持预准备语句:
TDS 4.2有局限性
- 当然,只有ASCII码。
- RPC不受支持。
- BCP不受支持。
- varchar字段限制为255个字符。 如果你的表定义了更长的字段,它们将被截断。
- dynamic查询(也称为准备语句)不受支持。
然而没有任何信息表明7.4不支持准备好的语句,这给了我合理的信心,他们至less不会抛出驱动错误。
PHP的PDO通过PDO::setAttribute()
支持特定于连接的属性。 我对PDO::ATTR_ERRMODE
感兴趣,将所有错误设置为exception, PDO::ATTR_EMULATE_PREPARES
强制数据库在兼容的情况下执行预处理语句。
问题
在testing连接时,我收到以下错误:
数据库错误:SQLSTATE [IM001]:驱动程序不支持此function:驱动程序不支持设置属性
无法设置PDO::ATTR_EMULATE_PREPARES
,我无法保证数据库正在按预期执行预准备语句。
有没有办法修改我的方法,或者有其他方法来保证准备好的语句在Linux上的MS SQL Server上安全地执行?
解
使用ODBC
而不是dblib
,它提供了PDO的全部功能。 请注意,有两种可能的ODBC配置: 独立的ODBC和带有ODBC驱动程序的FreeTDS 。 根据我的经验,为连接设置字符集,必须使用ODBC驱动程序通过FreeTDS完成,从而使组合配置更为可取。
ODBC安装程序
我搜索了许多不同的StackOverflow文章和网上的各种文档资源,以了解如何正确安装ODBC。 我从以下三个引用的混合中拉出我的解决方案:
FlipperPA
的答案设置 FlipperPA
(顺便做的ODBC) Benny Hill
对FreeTDS的这个设置问题的回答 以下是我在基于Debian的系统上使用FreeTDS
配置ODBC
的步骤列表。
TDS 8.0支持准备好的语句。
注意:不支持连接上的SET NAMES a
或SET CHARSET a
; 字符集需要通过设置FreeTDS属性来使用组合配置进行定义。 使用独立的ODBC驱动程序将字符集默认为ASCII
,这给了奇怪的结果。 看到我的其他职位的例子可能的问题。
安装需要包:
sudo apt-get install freetds-bin freetds-common unixodbc tdsodbc php5-odbc
freetds-bin
提供FreeTDS,以及tsql
和isql
(稍后用于调试)。 freetds-common
已经安装在系统上,但不包含两个调试工具。 定义配置后在以后安装freetds-bin
不会造成问题。 unixodbc
是ODBC驱动程序 tdsodbc
为ODBC提供了TDS协议 php5-odbc
是使用ODBC驱动程序的php模块。 请注意,您的PHP版本可能与我的不同。 配置独立的unixODBC
/etc/odbcinst.ini
ODBC驱动程序设置:
[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:
/etc/odbcinst.ini
ODBC驱动程序设置:
[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
在/etc/freetds/freetds.conf
中将ODBC数据源名称配置添加到FreeTDS:
[datasourcename] host = <IP or hostname> port = <port> client charset = UTF-8 tds version = 8.0 text size = 20971520 encryption = required
重要提示:确保odbc文件可以被正在读取的进程读取。 如果您使用
www-data
用户运行Web服务器,则必须具有正确的权限才能读取这些文件!
您现在可以在freetds.conf
设置连接字符集,并使用PDO连接到数据库
$pdo = new PDO('odbc:datasourcename');
测试:
使用tsql
检查FreeTDS是否已配置并可以连接到数据库。
tsql -S数据源名称-U用户名-P密码
使用isql
检查ODBC是否正确连接。
isql -v数据源名称用户名密码
链接ODBC与PHP:
通过添加以下内容将ODBC PHP模块添加到php.ini
:
扩展= odbc.so
请注意,您的php.ini
位置将取决于您正在使用的Web服务器。 使用<?php phpinfo(); ?>
<?php phpinfo(); ?>
并通过网络服务器查看它的位置。
重新启动Apache
编辑:添加有关驱动程序的字符集功能的信息,因为我遇到了独立的ODBC配置问题,它会忽略任何改变连接字符集的尝试。