代码之家  ›  专栏  ›  技术社区  ›  Stewart Smith

Linux上MS SQL Server通过PHP提供的非仿真准备语句支持

  •  5
  • Stewart Smith  · 技术社区  · 8 年前

    总结

    我正在尝试使用准备好的语句来停止SQL注入,但找不到所需的支持来保证它正常工作。


    脚本

    我在Linux上托管一个站点,该站点连接到一个带有FreeTDS 0.91版的Microsoft SQL Server,特别是使用FreeTDS's dblib .我已设置 tds 版本到7.4,用于数据库连接,am使用PHP PDO 对象

    根据 FreeTDS documentation ,4.2不支持准备语句:

    TDS 4.2有局限性

    • 当然,只有ASCII码。
    • 不支持RPC。
    • 不支持BCP。
    • varchar字段限制为255个字符。如果您的表定义 字段越长,它们将被截断。
    • 不支持动态查询(也称为预处理语句)。

    然而,没有任何迹象表明7.4不支持预置语句,这让我有理由相信它们至少不会抛出驱动程序错误。

    PHP的PDO通过以下方式支持特定于连接的属性 PDO::setAttribute() . 我对 PDO::ATTR_ERRMODE 将所有错误设置为异常,以及 PDO::ATTR_EMULATE_PREPARES 如果兼容,则强制数据库执行预处理语句。


    问题

    测试连接时,我收到以下错误:

    数据库错误:SQLSTATE[IM001]:驱动程序不支持此功能:驱动程序并不支持设置属性

    无法设置 PDO::ATTR_EMULATE_PREPARES ,我无法保证数据库实际上正在按预期执行准备好的语句。

    是否有任何方法可以修改我的方法,或者有其他方法可以

    1 回复  |  直到 8 年前
        1
  •  3
  •   Glorfindel Doug L.    3 年前

    解决方案

    使用 ODBC 而不是 dblib ,提供PDO的完整功能。 请注意,ODBC有两种可能的配置: standalone ODBC FreeTDS with ODBC driver 根据我的经验,要设置连接的字符集,必须使用ODBC驱动程序通过FreeTDS完成,这使得组合配置更可取。


    ODBC设置

    我在网上搜索了许多不同的StackOverflow文章和各种文档来源,了解如何正确安装ODBC。我从以下三个参考文献中提取了我的解决方案:

    ODBC公司 FreeTDS 基于Debian的系统上。

    TDS 8.0支持预处理语句。

    注意:不支持 SET NAMES a SET CHARSET a 在连接上;需要通过设置FreeTDS属性来使用组合配置定义字符集。使用独立ODBC驱动程序时,字符集默认为 ASCII ,得出了奇怪的结果。查看我的 other post 有关可能出现的问题的示例。

    安装所需的软件包:

    sudo apt-get安装freetds bin-freetds通用unixodbc tdsodbc 电话5 odbc

    • freetds-bin 提供FreeTDS,以及 tsql isql (稍后用于调试)。
    • freetds-common freetds垃圾箱 在稍后定义配置后,不会导致任何问题。
    • unixodbc 是ODBC驱动程序
    • tdsodbc 为ODBC提供TDS协议
    • php5-odbc 是用于使用ODBC驱动程序的php模块。请注意,您的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驱动程序设置 /等/odbcinst.ini :

    [odbc]
    描述=ODBC驱动程序
    驱动程序=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
    设置=/usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
    UsageCount=1
    

    在中创建系统范围的数据源名称配置 :

    [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');
    

    测试:

    使用 坦桑尼亚先令 检查FreeTDS是否已配置并可以连接到数据库。

    tsql-S数据源名称-U用户名-P密码

    使用 智能服务质量 以检查ODBC是否正确连接。

    isql-v数据源名称用户名密码

    将ODBC与PHP链接:

    将ODBC PHP模块添加到 php.ini 添加以下内容:

    扩展名=odbc.so

    请注意,您的 php.ini公司 位置将取决于您使用的web服务器。 使用 <?php phpinfo(); ?> 并通过web服务器查看它以找到它的位置。

    重新启动Apache

    编辑: 添加了有关驱动程序字符集功能的信息,因为我在使用独立ODBC配置时遇到了问题,它会忽略任何更改连接字符集的尝试。