2016-07-12 14 views
4

ZusammenfassungNicht Emulierte Prepared Statement Unterstützung von MS SQL Server über PHP auf Linux

ich vorbereitete Anweisungen zu verwenden bin versucht, SQL Injections zu stoppen, aber ich bin nicht in der Lage, die Unterstützung, die ich es zu gewährleisten, muß zu finden ist funktioniert richtig.


Szenario

ich eine Seite auf Linux ist Hosting, die mit FreeTDS Version 0.91 auf einen Microsoft SQL Server verbinden, speziell FreeTDS des dblib verwenden. Ich habe die tds Version auf 7.4 für die Datenbankverbindung eingestellt und verwende PHP PDO Objekt.

Nach den FreeTDS documentation, 4.2 unterstützen nicht Prepared Statements:

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.

aber es gibt nichts, was anzeigt, dass 7.4 nicht vorbereitete Anweisungen nicht unterstützt, was mir vernünftig Vertrauen gibt, am wenigsten sie nicht einen Wurf Treiberfehler

PHPs PDO unterstützt verbindungsspezifische Attribute über PDO::setAttribute(). Ich interessiere mich für PDO::ATTR_ERRMODE, um alle Fehler als Ausnahmen festzulegen, und PDO::ATTR_EMULATE_PREPARES, um die Datenbank zu zwingen, vorbereitete Anweisungen zu machen, wenn kompatibel.


Ausgabe

Wenn die Verbindung zu testen, erhalte ich folgende Fehlermeldung:

Database error: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes

Ohne PDO::ATTR_EMULATE_PREPARES einstellen zu können, ich bin nicht in der Lage die Datenbank zu gewährleisten, tatsächlich der Ausführung wird vorbereitete Aussagen wie vorgesehen.

Gibt es sowieso eine Änderung meines Ansatzes, oder gibt es einen alternativen Ansatz, um zu garantieren, dass vorbereitete Anweisungen sicher auf einem MS SQL Server von Linux ausgeführt werden?

Antwort

1

Lösung

Verwenden ODBC statt dblib, die die volle Funktionalität von PDO zur Verfügung stellt. Beachten Sie, dass es zwei mögliche Konfigurationen von ODBC gibt: standalone ODBC und FreeTDS with ODBC driver. Aus meiner Erfahrung muss der Zeichensatz für eine Verbindung über FreeTDS mithilfe des ODBC-Treibers festgelegt werden, sodass die kombinierte Konfiguration vorzuziehen ist.


ODBC Setup

ich durch viele verschiedene Stackoverflow Beiträge gesucht und verschiedene Dokumentationsquellen im Web, wie ODBC ordnungsgemäß zu installieren.Ich zog meine Lösung aus einer Mischung aus den folgenden drei Referenzen:

Unten finden Sie die Liste der Schritte, die ich verwendet habe, um ODBC mit FreeTDS auf einem Debian-basierten System zu konfigurieren.

TDS 8.0 unterstützt vorbereitete Anweisungen.

HINWEIS: Unterstützt oder SET CHARSET a nicht auf einer Verbindung; Zeichensätze müssen mithilfe der kombinierten Konfiguration definiert werden, indem ein FreeTDS-Attribut festgelegt wird. Bei Verwendung des eigenständigen ODBC-Treibers wurde der Zeichensatz standardmäßig auf ASCII gesetzt, was zu ungeraden Ergebnissen führte. Beispiele für mögliche Probleme finden Sie unter other post.

Installieren erfordern Pakete:

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

  • freetds-bin FreeTDS bietet sowie tsql und isql (für die Fehlersuche verwendet später).
  • freetds-common wurde bereits auf dem System installiert, enthält jedoch nicht die beiden Debugging-Tools. Die Installation von freetds-bin zu einem späteren Zeitpunkt, nachdem eine Konfiguration definiert wurde, verursacht kein Problem.
  • unixodbc ist der ODBC-Treiber
  • tdsodbc das TDS-Protokoll für ODBC bietet
  • php5-odbc wird das PHP-Modul verwendeten ODBC-Treiber. Beachten Sie, dass Ihre PHP-Version von meiner abweichen kann.

Server konfigurieren unixODBC

ODBC-Treiber-Einstellungen in /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 

erstellen systemweite Datenquellennamen Konfiguration in /etc/odbc.ini:

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

konfigurieren un ixODBC und FreeTDS:

ODBC-Treiber-Einstellungen in /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 

erstellen systemweite Datenquellennamen Konfiguration in /etc/odbc.ini:

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

Fügen Sie den ODBC-Datenquelle Name config FreeTDS in /etc/freetds/freetds.conf:

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!

können Sie legen nun die Verbindung Zeichensatz in freetds.conf und eine Verbindung zur Datenbank mit PDO als

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

Testing:

Verwenden tsql zu prüfen, ob FreeTDS konfiguriert und verbinden können, um die Datenbank.

tsql -S datasourcename -U username -P password

Verwenden isql zu prüfen, ob ODBC richtig verbindet.

isql -v datasourcename username password

Link-ODBC mit PHP:

hinzufügen ODBC PHP-Modul zu php.ini, indem Sie die folgenden Schritte aus:

extension = odbc.so

Beachten Sie, dass php.ini Standort wird davon abhängen, welche Webserver Sie verwenden. Verwenden Sie <?php phpinfo(); ?> und zeigen Sie es über den Webserver an, um seinen Standort zu finden.

Restart Apache

EDIT: Added Informationen über Zeichensatz-Fähigkeiten des Fahrers, wie ich in Probleme mit der Standalone-ODBC-Konfiguration lief, wo er jeden Versuch ignorieren würde die Verbindung des Zeichensatz zu ändern.