Thoát khỏi một chuỗi nghĩa là gì?


84

Tôi đang đọc Có cần phải thoát $ _SESSION ['tên người dùng'] trước khi truy vấn SQL không? và nó nói "Bạn cần phải thoát khỏi mọi chuỗi bạn chuyển đến truy vấn sql, bất kể nguồn gốc của nó là gì". Bây giờ tôi biết một cái gì đó như thế này là thực sự cơ bản. Một tìm kiếm trên Google cho ra hơn 20.000 kết quả. Chỉ riêng Stackoverflow đã có 20 trang kết quả nhưng không ai thực sự giải thích thoát chuỗi là gì hoặc cách thực hiện nó. Nó chỉ là giả định. Bạn có thể giúp tôi được không? Tôi muốn học vì như mọi khi tôi đang làm một ứng dụng web bằng PHP.

Tôi đã xem: Chèn các ký tự Escape , Tất cả các ký tự thoát trong Java là gì? , Không thể thoát một chuỗi với addcslashes () , Escape character , mysql_real_escape_string () thực sự làm được gì? , Làm cách nào để thoát khỏi dấu ngoặc kép từ một chuỗi trong php? , MySQL_real_escape_string không thêm dấu gạch chéo? , loại bỏ các chuỗi thoát khỏi chuỗi trong php Tôi có thể tiếp tục nhưng tôi chắc chắn rằng bạn hiểu đúng. Đây không phải là sự lười biếng.


10
Tái bút Tôi có thể chỉ hỏi một người bạn và không tự lừa mình nhưng tôi nghĩ sẽ có rất nhiều người giống như tôi tự hỏi điều mà mọi người đang nói về điều này là gì.
Brett

Câu trả lời:


136

Thoát khỏi một chuỗi có nghĩa là giảm sự mơ hồ trong dấu ngoặc kép (và các ký tự khác) được sử dụng trong chuỗi đó. Ví dụ: khi bạn xác định một chuỗi, bạn thường đặt nó trong dấu ngoặc kép hoặc dấu ngoặc đơn:

"Hello World."

Nhưng điều gì sẽ xảy ra nếu chuỗi của tôi có dấu ngoặc kép bên trong nó?

"Hello "World.""

Bây giờ tôi có sự mơ hồ - trình thông dịch không biết chuỗi của tôi kết thúc ở đâu. Nếu tôi muốn giữ dấu ngoặc kép của mình, tôi có một số lựa chọn. Tôi có thể sử dụng các dấu ngoặc kép xung quanh chuỗi của mình:

'Hello "World."'

Hoặc tôi có thể thoát khỏi báo giá của mình:

"Hello \"World.\""

Bất kỳ dấu ngoặc kép nào đứng trước dấu gạch chéo đều được thoát và được hiểu là một phần giá trị của chuỗi.

Khi nói đến truy vấn, MySQL có một số từ khóa nhất định mà nó theo dõi mà chúng ta không thể sử dụng trong các truy vấn của mình mà không gây ra một số nhầm lẫn. Giả sử chúng ta có một bảng các giá trị trong đó một cột được đặt tên là "Chọn" và chúng ta muốn chọn:

SELECT select FROM myTable

Bây giờ chúng tôi đã đưa ra một số điều không rõ ràng trong truy vấn của chúng tôi. Trong truy vấn của chúng tôi, chúng tôi có thể giảm sự mơ hồ đó bằng cách sử dụng dấu tích sau:

SELECT `select` FROM myTable

Điều này loại bỏ sự nhầm lẫn mà chúng tôi đã giới thiệu bằng cách sử dụng phán đoán kém trong việc chọn tên trường.

Rất nhiều điều này có thể được xử lý cho bạn bằng cách chuyển các giá trị của bạn qua mysql_real_escape_string(). Trong ví dụ bên dưới, bạn có thể thấy rằng chúng tôi đang chuyển dữ liệu do người dùng gửi thông qua chức năng này để đảm bảo rằng nó sẽ không gây ra bất kỳ sự cố nào cho truy vấn của chúng tôi:

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));

Các phương pháp khác tồn tại cho các chuỗi thoát, chẳng hạn như add_slashes, addcslashes, quotemeta, và nhiều hơn nữa, mặc dù bạn sẽ thấy rằng khi mục tiêu là để chạy một truy vấn an toàn, bởi các nhà phát triển và lớn thích mysql_real_escape_stringhoặc pg_escape_string(trong bối cảnh PostgreSQL.


6
Cần lưu ý rằng việc thực hiện thoát chuỗi để chống lại các vấn đề của SQL Injection được coi là hành động xấu và có thể dễ dàng dẫn đến các vấn đề bảo mật nếu không được thực hiện đúng cách (đặc biệt là khi xử lý một số kiểu tấn công ký tự nhiều byte không đúng định dạng). Vui lòng không bao giờ thoát chuỗi vì lý do này và thay vào đó hãy sử dụng các truy vấn sql được tham số hóa hoặc các thủ tục được lưu trữ.
Cheekysoft

22

Một số ký tự có ý nghĩa đặc biệt đối với cơ sở dữ liệu SQL mà bạn đang sử dụng. Khi những ký tự này đang được sử dụng trong một truy vấn, chúng có thể gây ra hành vi không mong muốn và / hoặc ngoài ý muốn bao gồm việc cho phép kẻ tấn công xâm phạm cơ sở dữ liệu của bạn. Để ngăn các ký tự này ảnh hưởng đến truy vấn theo cách này, chúng cần phải được thoát hoặc nói theo cách khác, cơ sở dữ liệu cần được thông báo để không coi chúng là các ký tự đặc biệt trong truy vấn này.

Trong trường hợp của mysql_real_escape_string()nó thoát \x00, \n, \r, \, ', "\x1athế này, khi không trốn thoát, có thể gây ra những vấn đề đã đề cập trước đó bao gồm tiêm SQL với một cơ sở dữ liệu MySQL.


1

Để đơn giản, về cơ bản bạn có thể hình dung dấu gạch chéo ngược "\" là một lệnh cho trình thông dịch trong thời gian chạy.

Ví dụ: trong khi giải thích câu lệnh này:

$txt = "Hello world!";

trong giai đoạn phân tích từ vựng (hoặc khi tách lên báo cáo kết quả vào thẻ cá nhân) này sẽ được các thẻ nhận dạng $, txt, =, ", Hello world!, ", và;

Tuy nhiên, dấu gạch chéo ngược trong chuỗi sẽ gây ra thêm một tập hợp các mã thông báo và được hiểu như một lệnh để thực hiện điều gì đó với ký tự ngay sau nó: ví dụ:

$txt = "this \" is escaped";

kết quả trong các thẻ sau: $, txt, =, ", this, \, ", is escaped, ", và;

trình thông dịch đã biết (hoặc có các tuyến đặt trước mà nó có thể thực hiện) phải làm gì dựa trên ký tự tiếp nối \mã thông báo. Vì vậy, trong trường hợp của "nó, hãy xử lý nó như một ký tự chứ không phải là lệnh end-of-string.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.