Tôi có thể bảo vệ chống lại SQL SQL bằng cách thoát khỏi trích dẫn đơn và đầu vào của người dùng xung quanh bằng dấu ngoặc đơn không?


139

Tôi nhận ra rằng các truy vấn SQL được tham số hóa là cách tối ưu để vệ sinh đầu vào của người dùng khi xây dựng các truy vấn có chứa đầu vào của người dùng, nhưng tôi tự hỏi có gì sai khi lấy đầu vào của người dùng và thoát khỏi bất kỳ dấu ngoặc đơn nào và bao quanh toàn bộ chuỗi bằng dấu ngoặc đơn. Đây là mã:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

Bất kỳ trích dẫn đơn nào mà người dùng nhập vào đều được thay thế bằng dấu ngoặc đơn, loại bỏ khả năng kết thúc chuỗi của người dùng, do đó, mọi thứ khác họ có thể nhập, chẳng hạn như dấu chấm phẩy, dấu phần trăm, v.v., đều sẽ là một phần của chuỗi và không thực sự được thực hiện như là một phần của lệnh.

Chúng tôi đang sử dụng Microsoft SQL Server 2000, do đó tôi tin rằng trích dẫn đơn là dấu phân tách chuỗi duy nhất và là cách duy nhất để thoát khỏi dấu phân cách chuỗi, vì vậy không có cách nào để thực thi bất cứ điều gì mà người dùng nhập vào.

Tôi không thấy cách nào để khởi động một cuộc tấn công SQL SQL chống lại điều này, nhưng tôi nhận ra rằng nếu điều này có khả năng chống đạn như tôi thì người khác sẽ nghĩ về nó và đó sẽ là thông lệ.

Có gì sai với mã này? Có cách nào để có được một cuộc tấn công tiêm SQL qua kỹ thuật vệ sinh này không? Mẫu đầu vào của người dùng khai thác kỹ thuật này sẽ rất hữu ích.


CẬP NHẬT:

Tôi vẫn không biết cách nào để khởi động một cuộc tấn công SQL SQL một cách hiệu quả đối với mã này. Một số người cho rằng dấu gạch chéo ngược sẽ thoát khỏi một trích dẫn và bỏ đoạn còn lại để kết thúc chuỗi để phần còn lại của chuỗi được thực thi như một phần của lệnh SQL và tôi nhận ra rằng phương thức này sẽ hoạt động để đưa SQL vào một cơ sở dữ liệu MySQL, nhưng trong SQL Server 2000, cách duy nhất (mà tôi có thể tìm thấy) để thoát khỏi một trích dẫn là với một trích dẫn khác; dấu gạch chéo ngược sẽ không làm điều đó.

Và trừ khi có một cách để ngăn chặn việc thoát khỏi trích dẫn đơn, không có phần còn lại nào của đầu vào người dùng sẽ được thực thi bởi vì tất cả sẽ được coi là một chuỗi liền kề.

Tôi hiểu rằng có nhiều cách tốt hơn để vệ sinh đầu vào, nhưng tôi thực sự quan tâm hơn đến việc tìm hiểu lý do tại sao phương pháp tôi cung cấp ở trên sẽ không hiệu quả. Nếu bất cứ ai biết bất kỳ cách cụ thể nào để thực hiện một cuộc tấn công tiêm nhiễm SQL chống lại phương pháp vệ sinh này, tôi rất muốn thấy nó.


17
@BryanH Thừa nhận không hiểu làm thế nào sự khôn ngoan được chấp nhận áp dụng cho một trường hợp cụ thể và yêu cầu một ví dụ về trường hợp cụ thể như vậy không phải là sự kiêu ngạo, đó là sự khiêm tốn. Trở nên khó chịu khi ai đó hỏi một ví dụ về lý do tại sao sự khôn ngoan thường được chấp nhận là đúng, mặt khác có thể đi qua như kiêu ngạo. Lý luận bằng các ví dụ cụ thể thường là một cách tuyệt vời để điều tra và học hỏi. Cách OP đi về nghi ngờ này rất hữu ích cho sự hiểu biết của tôi về chủ đề này, đặc biệt là khi anh ấy giải thích câu trả lời mà anh ấy tìm thấy.
SantiBailors

@patrik Chỉ tình cờ thấy điều này khi tôi đang làm việc trên cùng một đoạn mã nhưng cố gắng thoát khỏi chuỗi và lồng một truy vấn. Bạn đã bao giờ tìm ra nó?
3therk1ll

1
@ 3therk1 Sẽ tốt nhất không nên thử, tốt hơn hết là bạn nên sử dụng SQL được tham số hóa: blog.codinghorror.com/ Đổi
Patrick

@Patrick, tôi đang tiếp cận nó từ quan điểm của những kẻ tấn công!
3therk1ll

Câu trả lời:


87

Trước hết, đó chỉ là thực hành tồi. Xác nhận đầu vào luôn luôn cần thiết, nhưng nó cũng luôn luôn là iffy.
Tệ hơn nữa, xác nhận danh sách đen luôn có vấn đề, tốt hơn hết là xác định rõ ràng và nghiêm ngặt những giá trị / định dạng bạn chấp nhận. Phải thừa nhận rằng điều này không phải lúc nào cũng có thể - nhưng trong một chừng mực nào đó, nó phải luôn luôn được thực hiện.
Một số tài liệu nghiên cứu về chủ đề này:

Điểm là, bất kỳ danh sách đen nào bạn làm (và danh sách trắng quá dễ dãi) có thể được bỏ qua. Liên kết cuối cùng đến bài viết của tôi cho thấy các tình huống mà ngay cả trích dẫn thoát có thể được bỏ qua.

Ngay cả khi những tình huống này không áp dụng cho bạn, đó vẫn là một ý tưởng tồi. Hơn nữa, trừ khi ứng dụng của bạn nhỏ một cách tầm thường, bạn sẽ phải đối phó với bảo trì và có thể là một số lượng quản trị nhất định: làm thế nào để bạn đảm bảo rằng nó được thực hiện đúng, mọi lúc?

Cách thích hợp để làm điều đó:

  • Xác thực danh sách trắng: loại, độ dài, định dạng hoặc giá trị được chấp nhận
  • Nếu bạn muốn vào danh sách đen, hãy tiếp tục. Trích dẫn thoát là tốt, nhưng trong bối cảnh của giảm nhẹ khác.
  • Sử dụng các đối tượng Command và Parameter, để chuẩn bị và xác nhận
  • Chỉ gọi các truy vấn tham số.
  • Tốt hơn nữa, sử dụng Thủ tục lưu trữ độc quyền.
  • Tránh sử dụng SQL động và không sử dụng nối chuỗi để xây dựng truy vấn.
  • Nếu sử dụng SP, bạn cũng có thể giới hạn quyền trong cơ sở dữ liệu chỉ thực hiện các SP cần thiết và không truy cập trực tiếp vào bảng.
  • bạn cũng có thể dễ dàng xác minh rằng toàn bộ cơ sở mã chỉ truy cập DB thông qua SP ...

2
Khi được sử dụng một cách chính xác, SQL động và nối chuỗi có thể được sử dụng một cách an toàn với các truy vấn được tham số hóa (nghĩa là sp_executesqlthay vì EXEC). Đó là, bạn có thể tự động tạo câu lệnh SQL của mình miễn là không có văn bản được nối nào đến từ người dùng. Điều này cũng có lợi ích hiệu suất; sp_executesqlhỗ trợ bộ nhớ đệm.
Brian

2
@Brian, cũng duh :). Nhưng trong thực tế, bạn có thường thấy các lập trình viên làm điều đó không? Hơn nữa, kịch bản điển hình trong đó SQL động là "cần thiết", yêu cầu người dùng nhập vào như một phần của truy vấn (được cho là). Nếu bạn có thể làm sp_executesql, bạn sẽ không (thường) cần sql động ở vị trí đầu tiên.
AviD

Cuối cùng tôi đã gặp phải một tình huống khiến tôi nhận ra rằng có thể sử dụng unicode để lén lút thay thế chuỗi. Văn bản đầu vào được nhập vào Word, đã thay đổi dấu nháy đơn từ phiên bản thẳng xuống thành dấu nháy đơn "xoăn" (trông giống dấu phẩy), không bị ảnh hưởng bởi thay thế chuỗi nhưng được SQL coi là dấu phân cách chuỗi Người phục vụ. Cảm ơn câu trả lời AviD (và mọi người khác)!
Patrick

1
@ElRonnoco chắc chắn, nhưng tôi không giảm giá điều đó, vì tôi đã thấy nó trong tự nhiên nhiều lần hơn bạn nghĩ ...
AviD

1
@AviD Tôi đã cập nhật liên kết tới SQL Buôn lậu SQL mà bạn đã viết lên phiên bản duy nhất tôi có thể tìm thấy trực tuyến ... vui lòng cho chúng tôi biết nếu có một vị trí khác cho bài viết của bạn.
Michael Fredrickson

41

Được rồi, câu trả lời này sẽ liên quan đến việc cập nhật câu hỏi:

"Nếu bất cứ ai biết về bất kỳ cách cụ thể nào để thực hiện một cuộc tấn công tiêm nhiễm SQL chống lại phương pháp vệ sinh này, tôi rất muốn thấy nó."

Bây giờ, bên cạnh dấu gạch chéo ngược thoát khỏi MySQL - và có tính đến việc chúng ta thực sự đang nói về MSSQL, thực tế có 3 cách có thể vẫn là SQL tiêm mã của bạn

sSanitizedInput = "'" & Thay thế (sInput, "'", "''") & "'"

Hãy xem xét rằng những điều này sẽ không hợp lệ mọi lúc và rất phụ thuộc vào mã thực tế của bạn xung quanh nó:

  1. SQL Injection thứ hai - nếu một truy vấn SQL được xây dựng lại dựa trên dữ liệu được truy xuất từ ​​cơ sở dữ liệu sau khi thoát , dữ liệu được nối không bị hủy và có thể được SQL gián tiếp tiêm vào. Xem
  2. Cắt ngắn chuỗi - (phức tạp hơn một chút) - Kịch bản là bạn có hai trường, giả sử tên người dùng và mật khẩu và SQL ghép nối cả hai trường. Và cả hai trường (hoặc chỉ đầu tiên) có giới hạn cứng về chiều dài. Chẳng hạn, tên người dùng được giới hạn ở 20 ký tự. Giả sử bạn có mã này:
username = left(Replace(sInput, "'", "''"), 20)

Sau đó, những gì bạn nhận được - là tên người dùng, đã thoát, và sau đó được cắt thành 20 ký tự. Vấn đề ở đây - tôi sẽ dán câu trích dẫn của mình vào ký tự thứ 20 (ví dụ sau 19 a) và trích dẫn thoát của bạn sẽ được cắt bớt (trong ký tự thứ 21). Sau đó, SQL

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

kết hợp với tên người dùng không đúng định dạng nói trên sẽ dẫn đến mật khẩu đã nằm ngoài dấu ngoặc kép và sẽ chỉ chứa tải trọng trực tiếp.
3. Buôn lậu Unicode - Trong một số trường hợp nhất định, có thể chuyển một ký tự unicode cấp cao trông giống như một trích dẫn, nhưng không phải - cho đến khi nó đến cơ sở dữ liệu, đột nhiên nó xuất hiện . Vì nó không phải là một trích dẫn khi bạn xác nhận nó, nên nó sẽ dễ dàng ... Xem phản hồi trước đây của tôi để biết thêm chi tiết và liên kết với nghiên cứu ban đầu.


28

Tóm lại: Không bao giờ thực hiện truy vấn thoát khỏi chính mình. Bạn bị ràng buộc để có được một cái gì đó sai. Thay vào đó, hãy sử dụng các truy vấn được tham số hóa hoặc nếu bạn không thể làm điều đó vì một số lý do, hãy sử dụng một thư viện hiện có thực hiện điều này cho bạn. Không có lý do để tự làm điều đó.


2
Điều gì sẽ xảy ra nếu bạn phải đối phó với một cái gì đó như "bảng Google Fusion" ở đâu, afaik, không có thư viện trừu tượng nào có sẵn hỗ trợ phương ngữ của nó? Bạn đề nghị điều gì?
systempuntoout 17/07 '

20

Tôi nhận ra đây là một thời gian dài sau khi câu hỏi được hỏi, nhưng ..

Một cách để khởi động một cuộc tấn công vào thủ tục 'trích dẫn đối số' là cắt ngắn chuỗi. Theo MSDN, trong SQL Server 2000 SP4 (và SQL Server 2005 SP1), một chuỗi quá dài sẽ bị cắt ngắn một cách lặng lẽ.

Khi bạn trích dẫn một chuỗi, chuỗi tăng kích thước. Mỗi dấu nháy đơn được lặp lại. Điều này sau đó có thể được sử dụng để đẩy các phần của SQL bên ngoài bộ đệm. Vì vậy, bạn có thể cắt bỏ các phần của mệnh đề where một cách hiệu quả.

Điều này có lẽ hầu như hữu ích trong kịch bản trang 'quản trị viên người dùng' nơi bạn có thể lạm dụng tuyên bố 'cập nhật' để không thực hiện tất cả các kiểm tra cần thực hiện.

Vì vậy, nếu bạn quyết định trích dẫn tất cả các đối số, hãy chắc chắn rằng bạn biết điều gì xảy ra với kích thước chuỗi và xem nó không bị cắt ngắn.

Tôi khuyên bạn nên đi với các tham số. Luôn luôn. Chỉ muốn tôi có thể thực thi điều đó trong cơ sở dữ liệu. Và như là một tác dụng phụ, bạn có nhiều khả năng nhận được các lần truy cập bộ đệm tốt hơn vì nhiều câu lệnh trông giống nhau. (Điều này chắc chắn đúng trên Oracle 8)


1
Sau khi đăng, tôi quyết định rằng bài đăng của AviD bao gồm điều này, và chi tiết hơn. Hy vọng bài viết của tôi vẫn sẽ giúp ích cho ai đó.
Jørn Jensen

10

Tôi đã sử dụng kỹ thuật này khi xử lý chức năng 'tìm kiếm nâng cao', trong đó xây dựng truy vấn từ đầu là câu trả lời khả thi duy nhất. (Ví dụ: cho phép người dùng tìm kiếm sản phẩm dựa trên bộ ràng buộc không giới hạn đối với các thuộc tính sản phẩm, hiển thị các cột và giá trị được phép của chúng dưới dạng điều khiển GUI để giảm ngưỡng học tập cho người dùng.)

Bản thân nó là AFAIK an toàn. Tuy nhiên, như một người trả lời khác đã chỉ ra, bạn cũng có thể cần phải xử lý thoát backspace (mặc dù không phải khi chuyển truy vấn tới SQL Server bằng ADO hoặc ADO.NET, ít nhất - không thể bảo đảm cho tất cả các cơ sở dữ liệu hoặc công nghệ).

Điều khó khăn là bạn thực sự phải chắc chắn chuỗi nào chứa đầu vào của người dùng (luôn có khả năng gây hại) và chuỗi nào là truy vấn SQL hợp lệ. Một trong những cái bẫy là nếu bạn sử dụng các giá trị từ cơ sở dữ liệu - những giá trị đó ban đầu do người dùng cung cấp? Nếu vậy, họ cũng phải được trốn thoát. Câu trả lời của tôi là cố gắng vệ sinh càng muộn càng tốt (nhưng không muộn hơn!), Khi xây dựng truy vấn SQL.

Tuy nhiên, trong hầu hết các trường hợp, ràng buộc tham số là cách để đi - nó chỉ đơn giản hơn.


2
Bạn vẫn có thể sử dụng thay thế tham số ngay cả khi bạn đang xây dựng các truy vấn của riêng mình.
Nick Johnson

1
Bạn nên xây dựng chuỗi câu lệnh SQL từ đầu, nhưng vẫn sử dụng thay thế tham số.
JeeBee

Không, KHÔNG BAO GIỜ xây dựng các câu lệnh SQL của bạn từ đầu.
AviD

8

Vệ sinh đầu vào không phải là thứ bạn muốn nửa vời. Sử dụng toàn bộ mông của bạn. Sử dụng các biểu thức thông thường trên các trường văn bản. Hãy thử số của bạn theo loại số thích hợp và báo cáo lỗi xác thực nếu nó không hoạt động. Rất dễ dàng để tìm kiếm các mẫu tấn công trong đầu vào của bạn, chẳng hạn như '-. Giả sử tất cả đầu vào từ người dùng là thù địch.


4
Và khi bạn bỏ lỡ MỘT trường hợp đó trên MỘT đầu vào, bạn sẽ thấy.
BryanH

4
"Một số người, khi đối mặt với một vấn đề, nghĩ rằng" Tôi biết, tôi sẽ sử dụng các biểu thức thông thường. "Bây giờ họ có hai vấn đề."
MickeyfAgain_B BeforeExitOfSO 5/12/13

1
@mickeyf Tôi biết đây là một tình cảm phổ biến nhưng thành thật mà nói, biểu thức chính quy là khá tuyệt vời khi bạn grep chúng.
tom.dietrich

@ tom.dietrich Nó luôn phụ thuộc vào tình hình thực tế. F.ex Cú pháp regexpr không chuẩn, vì vậy, nói chung tôi sẽ khuyên bạn không nên sử dụng regexpr trong các ngữ cảnh nơi các hệ thống khác nhau được tích hợp để hoạt động cùng nhau. Điều này là do các công cụ regexpr khác nhau đánh giá regexprs khác nhau và quan trọng hơn là thực tế khó khăn này thường bị xem thường hoặc bị bỏ qua, điều này có thể khiến các nhà phát triển không quan tâm đến những sự không tương thích này cho đến khi họ bị cắn. Có rất nhiều sự không tương thích như vậy; xem f.ex. normal-expressions.info/shorthand.html (tìm kiếm flavorstrong trang đó).
SantiBailors

6

Dù sao thì đó cũng là một ý tưởng tồi.

Điều gì về một cái gì đó như thoát khỏi trích dẫn trong chuỗi như thế này: \ '

Sự thay thế của bạn sẽ dẫn đến: \ ''

Nếu dấu gạch chéo ngược thoát khỏi trích dẫn đầu tiên, thì trích dẫn thứ hai đã kết thúc chuỗi.


3
Cảm ơn vì sự trả lời! Tôi biết rằng cuộc tấn công sẽ hoạt động đối với cơ sở dữ liệu myQuery nhưng tôi khá chắc chắn rằng MS SQL Server sẽ không chấp nhận dấu gạch chéo ngược như một ký tự thoát (tôi đã thử nó). Một số tìm kiếm google không tiết lộ bất kỳ ký tự thoát nào khác, điều này thực sự khiến tôi tự hỏi tại sao điều này sẽ không hoạt động.
Patrick

6

Câu trả lời đơn giản: Đôi khi nó sẽ hoạt động, nhưng không phải tất cả thời gian. Bạn muốn sử dụng xác nhận danh sách trắng trên mọi thứ bạn làm, nhưng tôi nhận ra rằng điều đó không phải lúc nào cũng có thể, vì vậy bạn buộc phải đi theo danh sách đen đoán tốt nhất. Tương tự như vậy, bạn muốn sử dụng procs lưu trữ tham số trong mọi thứ , nhưng một lần nữa, điều đó không phải lúc nào cũng có thể, vì vậy bạn buộc phải sử dụng sp_execute với các tham số.

Có nhiều cách xung quanh bất kỳ danh sách đen có thể sử dụng mà bạn có thể đưa ra (và một số danh sách trắng cũng vậy).

Một bài viết hay ở đây: http://www.owasp.org/index.php/Top_10_2007-A2

Nếu bạn cần làm điều này như một cách khắc phục nhanh để cho bạn thời gian để có được một cái thực sự tại chỗ, hãy làm nó. Nhưng đừng nghĩ rằng bạn an toàn.


6

Có hai cách để làm điều đó, không có ngoại lệ, để an toàn khỏi các lệnh tiêm SQL; báo cáo chuẩn bị hoặc thủ tục lưu trữ tham số.


4

Nếu bạn có sẵn các truy vấn tham số, bạn nên sử dụng chúng mọi lúc. Tất cả chỉ cần cho một truy vấn lướt qua mạng và DB của bạn có nguy cơ.


4

Vâng, điều đó sẽ hoạt động ngay cho đến khi ai đó chạy SET QUOTED_IDENTIFIER TẮT và sử dụng một trích dẫn kép cho bạn.

Chỉnh sửa: Không đơn giản như không cho phép người dùng độc hại tắt định danh được trích dẫn:

Trình điều khiển ODBC SQL Client Client và SQL Server Client Client cho SQL Server tự động đặt QUOTED_IDENTIFIER thành ON khi kết nối. Điều này có thể được cấu hình trong các nguồn dữ liệu ODBC, trong các thuộc tính kết nối ODBC hoặc các thuộc tính kết nối OLE DB. Mặc định cho SET QUOTED_IDENTIFIER là TẮT cho các kết nối từ các ứng dụng Thư viện DB.

Khi một thủ tục được lưu trữ được tạo, các cài đặt SET QUOTED_IDENTIFIER và SET ANSI_NULLS được ghi lại và sử dụng cho các lần gọi tiếp theo của thủ tục được lưu trữ đó .

SET QUOTED_IDENTIFIER cũng tương ứng với cài đặt QUOTED_IDENTIFER của ALTER DATABASE.

SET QUOTED_IDENTIFIER được đặt ở thời gian phân tích cú pháp . Đặt tại thời điểm phân tích có nghĩa là nếu câu lệnh SET có mặt trong lô hoặc thủ tục được lưu trữ, nó sẽ có hiệu lực, bất kể việc thực thi mã có thực sự đạt đến điểm đó hay không; và câu lệnh SET có hiệu lực trước khi bất kỳ câu lệnh nào được thực thi.

Có rất nhiều cách QUOTED_IDENTIFIER có thể tắt mà bạn không nhất thiết phải biết. Phải thừa nhận rằng - đây không phải là khẩu súng khai thác mà bạn đang tìm kiếm, nhưng nó là một bề mặt tấn công khá lớn. Tất nhiên, nếu bạn cũng thoát được dấu ngoặc kép - thì chúng tôi sẽ quay lại nơi chúng tôi bắt đầu. ;)


1
Điều đó có thể hoạt động, nhưng một lần nữa, làm thế nào họ có thể thực thi mã đó khi tất cả đầu vào của người dùng được bao quanh bởi các dấu ngoặc đơn? Một dòng mã cụ thể có thể đưa SQL vào đoạn mã trên sẽ rất hữu ích. Cảm ơn!
Patrick

4

Phòng thủ của bạn sẽ thất bại nếu:

  • truy vấn đang mong đợi một số chứ không phải là một chuỗi
  • có bất kỳ cách nào khác để biểu thị một dấu ngoặc kép, bao gồm:
    • một chuỗi thoát như \ 039
    • một nhân vật unicode

(trong trường hợp sau, nó sẽ phải là một cái gì đó được mở rộng chỉ sau khi bạn thực hiện thay thế)


4

Patrick, bạn đang thêm dấu ngoặc đơn xung quanh TẤT CẢ đầu vào, thậm chí đầu vào số? Nếu bạn có đầu vào số, nhưng không đặt dấu ngoặc đơn xung quanh nó, thì bạn có một phơi sáng.


1

Những gì mã xấu xí tất cả những gì vệ sinh đầu vào của người dùng sẽ là! Sau đó, StringBuilder clunky cho câu lệnh SQL. Phương thức câu lệnh được chuẩn bị dẫn đến mã sạch hơn nhiều và các lợi ích SQL Injection là một bổ sung thực sự tốt đẹp.

Ngoài ra tại sao lại phát minh lại bánh xe?


1

Thay vì thay đổi một trích dẫn thành (trông giống như) hai trích dẫn đơn, tại sao không thay đổi nó thành dấu nháy đơn, trích dẫn hoặc xóa hoàn toàn?

Dù bằng cách nào, đó là một chút bùn ... đặc biệt là khi bạn hợp pháp có những thứ (như tên) có thể sử dụng dấu ngoặc đơn ...

LƯU Ý: Phương pháp của bạn cũng giả sử mọi người làm việc trên ứng dụng của bạn luôn nhớ phải vệ sinh đầu vào trước khi nó truy cập vào cơ sở dữ liệu, điều này có lẽ không thực tế trong hầu hết thời gian.


Bỏ phiếu vì câu trả lời không giải quyết câu hỏi. Câu hỏi là về thoát chuỗi trong SQL. Khi bạn thoát khỏi một chuỗi tùy ý (như người hỏi đang cố gắng thực hiện, để xử lý dữ liệu không được xác nhận), bạn không thể thay thế các ký tự có vấn đề bằng các ký tự khác tùy ý; làm hỏng dữ liệu. (Ngoài ra, một trích dẫn duy nhất là dấu nháy đơn (ít nhất là trong ASCII).)
andrewf

-1

Mặc dù bạn có thể tìm thấy một giải pháp hoạt động cho các chuỗi, nhưng đối với các vị từ số, bạn cũng cần đảm bảo rằng chúng chỉ truyền theo số (kiểm tra đơn giản là nó có thể được phân tích thành int / double / binary?).

Đó là rất nhiều công việc làm thêm.


-2

Nó có thể hoạt động, nhưng có vẻ như một con lợn nhỏ đối với tôi. Tôi khuyên bạn nên xác minh rằng mỗi chuỗi là hợp lệ bằng cách kiểm tra nó dựa vào biểu thức chính quy thay thế.


-3

Vâng, bạn có thể, nếu ...

Sau khi nghiên cứu chủ đề, tôi nghĩ đầu vào được khử trùng như bạn đề xuất là an toàn, nhưng chỉ theo các quy tắc sau:

  1. bạn không bao giờ cho phép các giá trị chuỗi đến từ người dùng trở thành bất kỳ thứ gì khác ngoài chuỗi ký tự (nghĩa là tránh đưa ra tùy chọn cấu hình: "Nhập tên / biểu thức cột SQL bổ sung tại đây:"). Các loại giá trị không phải là chuỗi (số, ngày, ...): chuyển đổi chúng thành kiểu dữ liệu gốc của chúng và cung cấp một thói quen cho SQL bằng chữ từ mỗi loại dữ liệu.

    • Các câu lệnh SQL có vấn đề để xác nhận
  2. bạn có thể sử dụng nvarchar/ ncharcột (và ký tự chuỗi tiền tố với N) HOẶC giới hạn giá trị đi vào varchar/ charcột thành các ký tự ASCII (ví dụ: ném ngoại lệ khi tạo câu lệnh SQL)

    • bằng cách này, bạn sẽ tránh được chuyển đổi dấu nháy đơn tự động từ CHAR (700) sang CHAR (39) (và có thể các bản hack Unicode tương tự khác)
  3. bạn luôn xác thực độ dài giá trị để phù hợp với chiều dài cột thực tế (ném ngoại lệ nếu dài hơn)

    • có một lỗi đã biết trong SQL Server cho phép bỏ qua lỗi SQL bị cắt khi cắt (dẫn đến cắt ngắn im lặng)
  4. bạn đảm bảo SET QUOTED_IDENTIFIERluôn luônON

    • hãy cẩn thận, nó có hiệu lực trong thời gian phân tích, tức là ngay cả trong các phần mã không thể truy cập

Tuân thủ 4 điểm này, bạn nên an toàn. Nếu bạn vi phạm bất kỳ trong số họ, một cách để SQL tiêm mở ra.


1
Giống như bạn đã không đọc tất cả các câu trả lời khác cho câu hỏi 8 tuổi này , vì bất kỳ số câu trả lời nào chỉ ra phương pháp của anh ta không dừng tiêm nếu kẻ tấn công chỉ đơn giản sử dụng các ký tự unicode.
Hogan

@Hogan - Tôi đã làm, nhưng tôi nghĩ có thêm giá trị trong câu hỏi của tôi. Tôi có nhiều kinh nghiệm và thử nghiệm đằng sau những gì tôi đã viết. Tôi biết sử dụng các tham số truy vấn là tốt hơn, nhưng tôi cũng hoàn toàn hiểu tình huống khi ai đó phải tránh nó vì nhiều lý do (ví dụ: nhà tuyển dụng yêu cầu giữ cách cũ). Trong trường hợp này, tôi nghĩ rằng câu trả lời của tôi rất toàn diện và có giá trị cao hơn câu trả lời rằng "đừng làm vậy", bởi vì nó cho thấy con đường xuyên suốt. Chỉ cho tôi các câu trả lời khác ở đây hiển thị theo cách tương tự và tôi sẽ xem xét xóa câu trả lời của tôi.
miroxlav

Ok, khi nào (không nếu) hệ thống của bạn bị xâm nhập, vui lòng quay lại và xóa câu trả lời này .... hoặc bạn có thể sử dụng truy vấn tham số.
Hogan

@Hogan - Tôi không có vấn đề gì để làm điều đó :) Nhưng hiện tại tôi khẳng định không có cách nào để khắc phục điều này nếu bạn giữ nguyên 4 quy tắc tôi đã đăng. Nếu bạn thực sự nghĩ rằng có một cách xung quanh nó, sau đó chỉ ra nơi.
miroxlav

Lời khuyên tồi hombre. bất kỳ nội suy có thể bị đánh bại.
Shayne
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.