摘要
我正在尝试使用预准备语句来停止SQL注入,但我无法找到我需要的支持以保证它正常工作.
脚本
我在Linux上托管一个站点,该站点连接到具有FreeTDS版本0.91的Microsoft SQL Server,特别是使用FreeTDS的dblib.我已将tds版本设置为7.4以进行数据库连接,并使用PHP的PDO对象.
根据FreeTDS documentation,4.2不支持准备好的声明:
TDS 4.2 has limitations
- ASCII only, of course.
- RPC is not supported.
- BCP is not supported.
- varchar fields are limited to 255 characters. If your table defines
longer fields, they’ll be truncated.- dynamic queries (also called prepared statements) are not supported.
但是没有任何迹象表明7.4不支持预处理语句,这给了我合理的信心,他们至少不会抛出驱动程序错误.
PHP的PDO通过PDO::setAttribute()
支持特定于连接的属性.
我感兴趣的是PDO :: ATTR_ERRMODE将所有错误设置为异常,而PDO :: ATTR_EMULATE_PREPARES则强制数据库在兼容时执行预准备语句.
问题
测试连接时,收到以下错误:
Database error: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes
如果无法设置PDO :: ATTR_EMULATE_PREPARES,我无法保证数据库实际上是按预期执行预准备语句.
无论如何都要修改我的方法,或者是否有替代方法
保证准备好的语句在Linux上的MS SQL Server上安全执行?
最佳答案 解
使用ODBC而不是dblib,它提供PDO的全部功能.
请注意,ODBC有两种可能的配置:standalone ODBC和FreeTDS with ODBC driver.根据我的经验,要设置连接的字符集,必须使用ODBC驱动程序通过FreeTDS完成,使组合配置更可取.
ODBC安装程序
我在网上搜索了许多不同的StackOverflow帖子和各种文档资源,了解如何正确安装ODBC.我从以下三个参考文献的混合中提取了我的解决方案:
> unixODBC setup documentation
> FlipperPA对setting up FreeTDS的回答(顺便完成了ODBC)
> Benny Hill对setup issue with FreeTDS的回答
下面是我在基于Debian的系统上使用FreeTDS配置ODBC的步骤列表.
TDS 8.0支持预准备语句.
注意:在连接上不支持SET NAMES a或SET CHARSET a;需要通过设置FreeTDS属性使用组合配置来定义字符集.使用独立的ODBC驱动程序将charset默认为ASCII,这会产生奇怪的结果.有关可能出现的问题的示例,请参阅我的other post.
安装require包:
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
IMPORTANT: make sure that the odbc files are readable by the process
that will be reading them. If you are running your webserver using a
www-data
user, they must have the proper permissions to read those
files!
您现在可以在freetds.conf中设置连接字符集,并使用PDO连接到数据库
$pdo = new PDO('odbc:datasourcename');
测试:
使用tsql检查FreeTDS是否已配置并可以连接到数据库.
tsql -S datasourcename -U username -P password
使用isql检查ODBC是否正确连接.
isql -v datasourcename username password
链接ODBC与PHP:
通过添加以下内容将ODBC PHP模块添加到php.ini:
extension = odbc.so
请注意,php.ini位置将取决于您使用的Web服务器.
使用<?php phpinfo(); ?>并通过网络服务器查看它以查找其位置. 重启Apache 编辑:
添加了有关驱动程序字符集功能的信息,因为我遇到了独立ODBC配置的问题,它会忽略任何更改连接字符集的尝试.