2010-01-05 5 views
8

Ich habe eine SQL-Anweisung, ähnlich dem unten in Perl gezeigt:Wie kann ich einfache und doppelte Anführungszeichen in SQL vorbereitete Anweisung entkommen lassen?

my $sql="abc..TableName '$a','$b' "; 

Die $ a freier Text, der alles andere einschließlich einfache Anführungszeichen, doppelte Anführungszeichen, Hinter- und Vorder-Slash-Zeichen enthalten, usw.

Wie können diese Zeichen maskiert werden, damit die SQL-Anweisung funktioniert?

Danke. entweder

+3

'$ a' und' $ b' haben eine besondere Bedeutung in Bezug auf die Funktion 'sort'. Es ist im Allgemeinen keine gute Idee, sie zu verwenden. Außer als kurze Variablennamen in einem Codebeispiel. – daotoad

+0

Anders als das [perl] -Tag, dup von [Der beste Weg, SQL Injection in PHP zu stoppen] (http://stackoverflow.com/q/60174/90527). Der einzige praktische Unterschied liegt in den Codebeispielen. Auch, dup von [Was ist der beste Weg, SQL-Injection-Angriffe zu vermeiden?] (Http://stackoverflow.com/q/1973/). – outis

Antwort

21

Sie können die ->quote Methode (vorausgesetzt, Sie verwenden DBI):

my $oldValue = $dbh->quote('oldValue'); 
my $newValue = $dbh->quote('newValue'); 
$dbh->do("UPDATE myTable SET myValue=$newValue where myValue=$oldValue"); 

noch besser, die beste Praxis ist binden Werte zu verwenden:

my $sth = $dbh->prepare('UPDATE myTable SET myValue=? WHERE myValue=?'); 

$sth->execute('newValue','oldValue'); 

Dies auch funktionieren soll Bei Stored Procedure-Aufrufe ist die SQL-Anweisung gültig, wenn die Anweisung nach dem Erweitern der Strings ausgeführt wird. Dies kann Treiber/DB-spezifisch sein, also YMMV.

my $sth = $dbh->prepare("DBName..ProcName ?,? "); 
$sth->execute($a, $b); 
+0

Es tut mir leid, dass ich nicht klar bin. Ich rufe eine gespeicherte Prozedur an. Das Beispiel sollte so aussehen: my $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

+5

Die Verwendung von Bindeparametern sollte weiterhin für Aufrufe von gespeicherten Prozeduren funktionieren. – mopoke

+0

Und falls es nicht offensichtlich ist, wenn Sie Bindungsparameter verwendet haben UND Sie manuell einfache Anführungszeichen für Ihre Werte vor dem Ausführen der Einfügung entfernt haben, dann wird der Spaltenwert mit zwei sequentiellen einfachen Anführungszeichen für jedes einzelne Anführungszeichen enden. – RTF

9

Verwenden Sie eine vorbereitete Anweisung. Ersetzen Sie die Variable durch ein?. Um ein Beispiel von DBI manpages Krippe:

$sql = 'SELECT * FROM people WHERE lastname = ?'; 
$sth = $dbh->prepare($sql); 
$sth->execute($user_input_here); 

Interpolieren von Benutzereingaben in den SQL für Sicherheitslücken zu fragen.

+0

Es tut mir leid, dass ich nicht klar bin. Ich rufe eine gespeicherte Prozedur an. Das Beispiel sollte etwa so aussehen: my $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

6

Wenn Sie Platzhalter für Abfrageparameter verwenden, müssen Sie den Inhalt der Zeichenfolgen nicht ausschließen.

my $sql="DBName..ProcName ?, ?"; 
$sth = $dbh->prepare($sql); 
$sth->execute($a, $b); 

Wenn die DBI wahre Abfrageparameter verwendet, sendet er die Parameterwerte an das RDBMS separat von der SQL-Anweisung. Die Werte werden niemals mit der SQL-Anweisungszeichenfolge kombiniert, daher haben die Werte nie die Möglichkeit, SQL-Injection zu verursachen.

Wenn der DBI vorbereitete Anweisungen "emuliert", indem er die Variablen in die Abfragezeichenfolge interpoliert, sollte DBI die korrekte Escape-Logik verarbeiten, so dass Sie nicht müssen. Lassen Sie die Experten (diejenigen, die DBI schreiben und testen) sich Gedanken darüber machen, wie es geht.

3

Wenn Sie nicht verwenden möchten -> Zitat (aus irgendeinem Grund, diese Funktion auf meine Version von DBI nicht ausgeführt wird), dann versuchen Sie dies:

$query=~s/\"/\\\"/g; 

Ich neige dazu, das gleiche zu tun mit einfache Anführungszeichen und Kommas, nur um sicher zu sein.

Scheint für mich gut zu funktionieren ...!

Verwandte Themen