Thực ra có hai câu hỏi trong một. Và câu hỏi từ tiêu đề có rất ít liên quan đến mối quan tâm của OP trong các bình luận sau đó.
Mặc dù tôi nhận thấy rằng đối với OP thì vấn đề cụ thể của họ mới là vấn đề quan trọng, đối với độc giả đến từ Google, điều quan trọng là phải trả lời cho câu hỏi tổng quát hơn, có thể được diễn giải là "nối an toàn như các câu đã chuẩn bị sẵn nếu tôi chắc chắn rằng mọi chữ tôi đang nối có an toàn không? ". Vì vậy, tôi muốn tập trung vào phần sau này. Và câu trả lời là
Tất nhiên là không.
Lời giải thích không trực tiếp như hầu hết độc giả mong muốn, nhưng tôi sẽ cố gắng hết sức.
Tôi đã cân nhắc về vấn đề này trong một thời gian, dẫn đến bài viết (mặc dù dựa trên môi trường PHP), nơi tôi đã cố gắng tổng hợp mọi thứ. Tôi nhận ra rằng câu hỏi về việc bảo vệ khỏi SQL injection thường bị né tránh đối với một số chủ đề có liên quan nhưng hẹp hơn, như thoát chuỗi, ép kiểu, v.v. Mặc dù một số biện pháp có thể được coi là an toàn khi tự thực hiện, nhưng không có hệ thống, cũng như quy tắc đơn giản để tuân theo. Điều này làm cho nền đất rất trơn trượt, đặt quá nhiều vào sự chú ý và kinh nghiệm của nhà phát triển.
Câu hỏi về SQL injection không thể được đơn giản hóa thành một vấn đề cú pháp cụ thể nào đó. Nó rộng hơn các nhà phát triển trung bình thường nghĩ. Đó cũng là một câu hỏi về phương pháp luận . Nó không chỉ là "Chúng tôi phải áp dụng định dạng cụ thể nào", mà còn là " Nó phải được thực hiện như thế nào ".
(Từ quan điểm này, một bài báo của Jon Skeet được trích dẫn trong câu trả lời khác đang làm khá tệ hơn là tốt, vì nó lại phản bác một số trường hợp phức tạp, tập trung vào một vấn đề cú pháp cụ thể và không giải quyết được toàn bộ vấn đề.)
Khi bạn đang cố gắng giải quyết câu hỏi bảo vệ không phải toàn bộ mà là một loạt các vấn đề cú pháp khác nhau, bạn đang đối mặt với vô số vấn đề.
- danh sách các lựa chọn định dạng có thể thực sự rất lớn. Có nghĩa là người ta có thể dễ dàng bỏ qua một số. Hoặc nhầm lẫn chúng (bằng cách sử dụng chuỗi thoát cho mã định danh chẳng hạn).
- Kết hợp có nghĩa là tất cả các biện pháp bảo vệ phải được thực hiện bởi lập trình viên, không phải chương trình. Chỉ riêng vấn đề này đã dẫn đến một số hậu quả:
- định dạng như vậy là thủ công. Thủ công có nghĩa là rất dễ xảy ra lỗi. Đơn giản là người ta có thể quên nộp đơn.
- hơn nữa, có một sự cám dỗ để di chuyển các thủ tục định dạng vào một số chức năng tập trung, làm mọi thứ rối tung hơn nữa và làm hỏng dữ liệu không được đưa vào cơ sở dữ liệu.
- khi có nhiều nhà phát triển tham gia, các vấn đề sẽ nhân lên với hệ số mười.
- khi phép nối được sử dụng, người ta không thể chỉ ra một truy vấn tiềm ẩn nguy hiểm: tất cả chúng đều tiềm ẩn nguy hiểm!
Không giống như mớ hỗn độn đó, những tuyên bố chuẩn bị thực sự là Chén Thánh:
- nó có thể được diễn đạt dưới dạng một quy tắc đơn giản dễ làm theo.
- về cơ bản nó là biện pháp không thể lưu trữ, có nghĩa là nhà phát triển không thể can thiệp, và dù cố ý hay không cố ý, làm hỏng quá trình.
- bảo vệ khỏi tiêm thực sự chỉ là một tác dụng phụ của các câu lệnh chuẩn bị, mục đích thực sự là tạo ra câu lệnh đúng cú pháp. Và một câu lệnh đúng về mặt cú pháp là bằng chứng tiêm 100%. Tuy nhiên, chúng tôi cần cú pháp của chúng tôi phải chính xác bất chấp khả năng tiêm bất kỳ.
- nếu được sử dụng tất cả các cách xung quanh, nó bảo vệ ứng dụng bất kể kinh nghiệm của nhà phát triển. Nói rằng, có một thứ gọi là tiêm bậc hai . Và một ảo tưởng rất mạnh rằng "để bảo vệ, Thoát khỏi Tất cả Đầu vào do Người dùng Cung cấp ". Kết hợp với nhau, chúng sẽ dẫn đến sự tiêm nhiễm, nếu một nhà phát triển có quyền tự do quyết định, điều gì cần được bảo vệ và điều gì không.
(Suy nghĩ xa hơn, tôi phát hiện ra rằng tập hợp các trình giữ chỗ hiện tại không đủ cho nhu cầu thực tế và phải được mở rộng, cho cả các cấu trúc dữ liệu phức tạp, như mảng và thậm chí cả từ khóa hoặc mã định danh SQL, đôi khi phải được thêm vào truy vấn động cũng vậy, nhưng một nhà phát triển không có vũ khí cho trường hợp như vậy và buộc phải quay lại nối chuỗi nhưng đó là vấn đề của một câu hỏi khác).
Điều thú vị là, tranh cãi của câu hỏi này bị kích động bởi tính chất gây tranh cãi của Stack Overflow. Ý tưởng của trang web là sử dụng các câu hỏi cụ thể từ những người dùng hỏi trực tiếp để đạt được mục tiêu là có cơ sở dữ liệu các câu trả lời cho mục đích chung phù hợp với những người dùng đến từ tìm kiếm . Ý tưởng này không phải là xấu cho mỗi gia nhập , nhưng nó bị lỗi trong một tình huống như thế này: khi người dùng yêu cầu một câu hỏi rất hẹp , đặc biệt là để có được một cuộc tranh cãi trong một tranh chấp với một đồng nghiệp (hoặc quyết định nếu nó có giá trị để cấu trúc lại mã). Trong khi hầu hết những người tham gia có kinh nghiệm đang cố gắng viết câu trả lời, hãy ghi nhớ nhiệm vụ về tổng thể Stack Overflow, làm cho câu trả lời của họ tốt cho càng nhiều người đọc càng tốt, chứ không chỉ OP.