2016-07-12 8 views
4

摘要通過PHP Linux上的非模擬從MS SQL服務器預處理語句支持

我試圖用準備好的發言停止SQL注入,但我無法找到我需要確保它是支持好好工作。


方案

我主持Linux上的網站被連接到一個Microsoft SQL Server與freetds的版本0.91,特別是使用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上安全地執行?

回答

1

解決方案

使用ODBC代替dblib,它提供了PDO的全部功能。 請注意,有兩種可能的ODBC配置:standalone ODBCFreeTDS with ODBC driver。根據我的經驗,爲連接設置字符集,必須使用ODBC驅動程序通過FreeTDS完成,從而使組合配置更爲可取。


ODBC安裝

我經歷了許多不同的StackOverflow職位,並就如何正確安裝ODBC網絡上的各種文檔資源搜索。我把我的解決方案從以下三個引用的混合物:「

  • Benny Hill的回答到setting up FreeTDS(順便用ODBC做)的回答

    以下是我在基於Debian的系統上使用FreeTDS配置ODBC的步驟列表。

    TDS 8.0支持預處理語句。

    注意:在連接上不支持SET NAMES aSET CHARSET a;字符集需要通過設置FreeTDS屬性使用組合配置來定義。使用獨立的ODBC驅動程序將字符集默認爲ASCII,這給出了奇怪的結果。有關可能的問題的示例,請參閱我的other post

    安裝需要的軟件包:

    sudo apt-get install freetds-bin freetds-common unixodbc tdsodbc php5-odbc

    • freetds-bin提供freetds的,以及tsqlisql(用於調試更高版本)。
    • freetds-common已經安裝在系統上,但不包括兩個調試工具。在定義配置後的稍後日期安裝freetds-bin不會導致問題。
    • unixodbc是ODBC驅動程序
    • tdsodbc提供ODBC
    • php5-odbc TDS協議是PHP模塊二手ODBC驅動程序。請注意,您的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 
    

    未配置ixODBC和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 
    

    添加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 
    

    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位置將取決於您所使用的網絡服務器。 使用<?php phpinfo(); ?>並通過網絡服務器查看它的位置。

    重啓Apache

    編輯: 與駕駛員的字符集的功能添加信息,因爲我遇到了與獨立的ODBC配置哪裏會忽略任何試圖更改連接的字符集問題。