2010-01-05 38 views
8

Tôi có một câu lệnh SQL tương tự như hình dưới đây trong Perl:Làm cách nào để thoát khỏi các dấu nháy đơn và kép trong câu lệnh SQL đã chuẩn bị?

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

Các $ a là văn bản miễn phí mà có thể chứa bất cứ điều gì kể cả dấu nháy đơn, dấu ngoặc kép, nhân vật back- và front-slash vv

Làm cách nào để các ký tự này có thể được thoát để làm cho câu lệnh SQL hoạt động?

Cảm ơn.

+3

'$ a' và' $ b' có ý nghĩa đặc biệt liên quan đến hàm 'sắp xếp'. Nó thường không phải là một ý tưởng tốt để sử dụng chúng. Ngoại trừ các tên biến ngắn trong một mẫu mã. – daotoad

+0

Khác với thẻ [perl], dup của [Cách tốt nhất để dừng SQL Injection trong PHP] (http://stackoverflow.com/q/60174/90527). Sự khác biệt thực tế duy nhất nằm trong các mẫu mã. Ngoài ra, dup của [cách tốt nhất để tránh các cuộc tấn công SQL injection là gì?] (Http://stackoverflow.com/q/1973/). – outis

Trả lời

21

Bạn có thể sử dụng phương pháp ->quote (giả sử bạn đang sử dụng DBI):

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

Vẫn còn tốt hơn, việc thực hành tốt nhất là sử dụng các giá trị ràng buộc:

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

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

này cũng nên làm việc cho các cuộc gọi thủ tục lưu trữ, giả sử câu lệnh một khi các chuỗi đã được mở rộng là SQL hợp lệ. Đây có thể là trình điều khiển/DB cụ thể để YMMV.

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

Tôi xin lỗi vì không rõ ràng. Tôi đang thực hiện một cuộc gọi đến một thủ tục được lưu trữ. Ví dụ nên có một cái gì đó như dưới đây: của tôi $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

+5

Sử dụng các thông số liên kết sẽ vẫn hoạt động cho các cuộc gọi thủ tục được lưu trữ. – mopoke

+0

Và trong trường hợp không rõ ràng, nếu bạn đã sử dụng các tham số liên kết VÀ bạn đã tự thoát dấu nháy đơn trên giá trị của bạn trước khi thực hiện chèn, thì giá trị cột sẽ kết thúc với hai dấu nháy đơn tuần tự cho mỗi dấu nháy đơn. – RTF

9

Sử dụng câu lệnh đã chuẩn bị. Thay thế biến bằng?. Để viết một ví dụ từ trang quản trị DBI:

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

Nội suy đầu vào của người dùng vào SQL của bạn là yêu cầu lỗ hổng bảo mật.

+0

Tôi xin lỗi vì không rõ ràng. Tôi đang thực hiện một cuộc gọi đến một thủ tục được lưu trữ. Ví dụ này phải giống như sau: $ sql = "DBName..ProcName '$ a', '$ b'"; – Sam

6

Nếu bạn sử dụng trình giữ chỗ thông số truy vấn, bạn không phải thoát khỏi nội dung của chuỗi.

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

Nếu DBI sử dụng tham số truy vấn thực, nó sẽ gửi giá trị tham số đến RDBMS tách biệt với câu lệnh SQL. Các giá trị không bao giờ được kết hợp với chuỗi câu lệnh SQL, do đó các giá trị không bao giờ có cơ hội gây ra SQL injection.

Nếu DBI là "mô phỏng" các câu lệnh đã được chuẩn bị bằng cách nội suy các biến vào chuỗi truy vấn, thì DBI sẽ xử lý logic thoát đúng để bạn không phải làm như vậy. Hãy để các chuyên gia (những người viết và kiểm tra DBI) lo lắng về việc làm thế nào để làm điều đó.

3

Nếu bạn không muốn sử dụng -> quote (đối với một số lý do, chức năng này không chạy trên phiên bản của tôi về DBI) sau đó thử này:

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

Tôi có xu hướng làm điều tương tự với dấu nháy đơn và dấu phẩy quá chỉ để được an toàn.

Dường như làm việc tốt cho tôi ...!

Các vấn đề liên quan