2010-01-07 74 views
7

Sự cốBảo vệ chống lại cuộc tấn công tiêm 'sqITFOR DELAY' sql injection?

Chúng tôi cần phòng thủ chống tấn công 'WAITFOR DELAY' sql injection trong ứng dụng java của chúng tôi.

nền

[Đây là dài. Chuyển đến 'Giải pháp?' bên dưới nếu bạn đang vội vàng]

Ứng dụng của chúng tôi chủ yếu sử dụng câu lệnh đã chuẩn bị và báo cáo có thể gọi (thủ tục lưu trữ) khi truy cập cơ sở dữ liệu.

Ở một vài nơi, chúng tôi tự động tạo và thực thi truy vấn để chọn. Trong mô hình này, chúng tôi sử dụng một đối tượng tiêu chí để xây dựng truy vấn tùy thuộc vào tiêu chí đầu vào của người dùng. Ví dụ, nếu người dùng xác định giá trị cho first_name và last_name, kết quả truy vấn luôn trông giống như sau:

SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier' 

(Trong ví dụ này, người dùng sẽ có quy định "joe" và "frazier" như/input của mình Nếu người dùng có nhiều hay ít critieria chúng tôi sẽ có các truy vấn dài hơn hoặc ngắn hơn. Chúng tôi nhận thấy rằng phương pháp này dễ hơn việc sử dụng các câu lệnh đã chuẩn bị và nhanh hơn/nhiều hơn các thủ tục lưu sẵn).

Vụ tấn công

Một kiểm toán lỗ hổng đã báo cáo một thất bại sql injection. Kẻ tấn công tiêm giá trị 'frazier WAITFOR TRÌ HOÃN '00: 00: 20' cho tham số 'last_name, dẫn đến sql này:

SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier' WAITFOR DELAY '00:00:20' 

Kết quả: truy vấn thực hiện thành công, nhưng mất 20 giây để thực thi. Kẻ tấn công có thể kết nối tất cả các kết nối cơ sở dữ liệu của bạn trong nhóm db và tắt trang web của bạn một cách hiệu quả.

Một số quan sát về cuộc tấn công này 'WAITFOR TRÌ HOÃN'

  • Tôi đã nghĩ rằng vì chúng tôi sử dụng Statement executeQuery (String), chúng tôi sẽ được an toàn từ sql injection. executeQuery (String) sẽ không thực hiện DML hoặc DDL (xóa hoặc giảm). Và các chuỗi lệnh executeQuery (String) trên bán dấu hai chấm, do đó mô hình 'Bảng Bobby' sẽ thất bại (tức là người dùng nhập 'yếu hơn; thành viên DROP TABLE' cho tham số. http://xkcd.com/327/)

  • Cuộc tấn công 'WAITFOR' khác nhau trong một khía cạnh quan trọng: WAITFOR sửa đổi lệnh 'SELECT' hiện tại, và không phải là một lệnh riêng biệt.

  • Cuộc tấn công chỉ hoạt động trên 'thông số cuối cùng' trong truy vấn kết quả. ví dụ: 'WAITFOR' phải xảy ra vào cuối của báo cáo sql

Solution, giá rẻ Hack, hoặc cả hai?

Giải pháp rõ ràng nhất đòi hỏi chỉ cần gắn "AND 1 = 1" vào mệnh đề where.

Các sql dẫn đến thất bại ngay lập tức và lá kẻ tấn công:

SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier' WAITFOR DELAY '00:00:20' AND 1=1 

Các câu hỏi

  • Đây có phải là một giải pháp khả thi cho cuộc tấn công WAITFOR?
  • Ứng dụng có chống lại các lỗ hổng tương tự khác không?
  • Tôi nghĩ rằng tùy chọn tốt nhất sẽ đòi hỏi bằng cách sử dụng câu lệnh đã chuẩn bị. Nhiều công việc hơn, nhưng ít bị tổn thương hơn.
+6

tiếc là người duy nhất nó là chính bạn. Nếu bạn tiếp tục, thay vì trì hoãn, "HOẶC 1 = 1", bạn có thể kết thúc cho phép bất kỳ ai và mọi người đăng nhập. Đừng cố lừa mình nghĩ rằng bạn có thể quản lý để outsmart tất cả những người muốn thử phá vỡ trang web của bạn. Bạn là một người, nếu trang web của bạn phổ biến, họ rất nhiều. Nếu không, thì có lẽ không thành vấn đề, nếu có, bạn làm. –

+0

quy tắC# 1: không tổng hợp và thực thi mã từ các nguồn không đáng tin cậy ... –

Trả lời

22

Cách chính xác để xử lý SQL injection là sử dụng truy vấn được tham số hóa. Mọi thứ khác chỉ là bực bội trong gió. Nó có thể làm việc một lần, thậm chí hai lần, nhưng cuối cùng bạn sẽ bị ảnh hưởng bởi cảm giác ấm áp đó nói rằng "bạn hơi say, tệ lắm!" Bất cứ điều gì bạn làm, ngoại trừ các truy vấn được tham số hóa, sẽ là phụ tối ưu, và nó sẽ tùy thuộc vào bạn để đảm bảo giải pháp của bạn không có các lỗ hổng khác mà bạn cần vá.

Truy vấn tham số hóa, mặt khác, hoạt động ra khỏi hộp và ngăn tất cả các cuộc tấn công này.

+0

Điểm tốt, tôi đoán tôi nên có được cụ thể hơn - một tuyên bố chuẩn bị sẽ không làm bạn bất kỳ tốt nếu bạn vượt qua nó một chuỗi nối lớn thay vì một với placeholders tham số! – Aaronaught

+3

Đó là lý do tại sao tôi đã nói "truy vấn tham số", không phải "truy vấn chuẩn bị". –

+1

"Cách chính xác để xử lý SQL injection là sử dụng các truy vấn được tham số hóa. Mọi thứ khác chỉ là pissing trong gió" Cảm ơn bạn đã nói sự thật! Đây là câu trả lời cho hầu như bất kỳ vấn đề lập trình an ninh thực sự. –

11

SQL injection là SQL injection - không có gì đặc biệt về một WAITFOR DELAY.

Hoàn toàn không có lý do gì để không sử dụng câu lệnh đã chuẩn bị cho truy vấn đơn giản như vậy trong ngày và tuổi này.

(Edit: Được rồi, không phải là "hoàn toàn" - nhưng có hầu như không bao giờ một cái cớ)

+0

tìm mã, một số phương pháp DAO 'finder' tạo 'IN mệnh đề' (nghĩa là "WHERE STATUS in (1,2,3) "). Không bào chữa, nhưng đây là những khó khăn hơn với các phát biểu đã chuẩn bị. – user72150

+2

Không thực sự. Chỉ cần tham số hóa các thẻ IN riêng lẻ ('WHERE status IN (?,?,?)'). – Aaronaught

+0

một nếp nhăn: kích thước danh sách có thể thay đổi. kích thước danh sách động hiển thị sự cố, AFAIK sql chuẩn bị sẵn sàng có thể có danh sách dài '?' (nghĩa là giới hạn trên của kích thước danh sách); bạn có thể đặt 3 đầu tiên và sử dụng setNull để đặt phần trên cùng bên trái-3. nghĩa là: WHERE trạng thái IN (?,?,?,?,?,?,?,?,?,?) – user72150

-4

Làm thế nào về sau xkcd và khử trùng đầu vào. Bạn có thể kiểm tra các từ dành riêng nói chung và WAITFOR nói riêng.

+5

Xin vui lòng, không. Đừng cố gắng khử trùng với một số hệ thống danh sách đen không ổn định. Nếu bạn có một chút ác cảm bí ẩn nhưng mãnh liệt đối với các phát biểu đã chuẩn bị thì * thoát * các chuỗi. – Aaronaught

+0

Tôi không -1 bạn, nhưng có vẻ như, câu đầu tiên của câu trả lời của bạn có thể đảm bảo +1 (vì nó đề cập đến xkcd), nhưng sau đó bạn nhận được câu thứ hai. Và đó là nơi tất cả sụp đổ. – shylent

+0

Banning từ khóa dành riêng là một chiến lược chỉ TSA có thể đủ khả năng để chi tiêu hàng tỷ và nhận được ngay với. – Coincoin

3

Tôi nghĩ bạn đã tự đề xuất giải pháp: Truy vấn tham số.

Làm cách nào bạn thấy rằng truy vấn được tạo động của bạn nhanh hơn việc sử dụng quy trình được lưu trữ? Nói chung nó thường là ngược lại.

+0

Ah vâng. Nói chung là đúng, nhưng trong những trường hợp cụ thể này, chúng tôi đã tìm ra cách khác. Đây là tình huống: bạn có phương thức DAO có đối tượng đặc điểm/tiêu chí với 30 trường trên đó. Bạn có thể có một thủ tục lưu trữ với 30 thông số về nó với sql trông như thế này: CHỌN last_name, first_name TỪ viên ĐÂU (@pLastName IS NULL OR @ pLastName = last_name) AND (@pFirstName IS NULL OR @ pFirstName = first_name) AND (@pSerialNbr IS NULL OR @ pSerialNbr = serial_nbr) AND (@pZodiacSign IS NULL OR @ pZodiacSign = zodiac_sign) AND (@pPartyRank IS NULL OR @ pPartyRank = party_rank) – user72150

+0

từ kinh nghiệm của tôi, Tối ưu hóa SQL/động cơ thực hiện rất kém trên các thủ tục như vậy; họ tái sử dụng một kế hoạch truy cập rất chung chung (thường là quét toàn bộ bảng) thay vì nhận biết trực tiếp để sử dụng một chỉ mục cụ thể. Ngoài ra, một số giá trị nằm trong danh sách thực tế (ví dụ: 'WHERE rank in (1,2,3)'). Tôi có ở các vị trí được chuyển trong các danh sách được phân tách bằng dấu phẩy, được phân tích cú pháp và điền một bảng tạm thời và tham gia vào bảng tạm thời nhưng thực tế này thực hiện * MUCH WORSE * so với một sql đơn giản với mệnh đề in. – user72150

+0

cuối cùng, để tóm tắt, từ kinh nghiệm của tôi: sql đơn giản thực hiện tốt nhất. Super-fancy sql làm cho siêu chậm. Trình tối ưu hóa và trình tạo kế hoạch truy cập không thông minh. (chúng tôi cũng hỗ trợ một vài db khác nhau để có giới hạn số lượng gợi ý chúng tôi có thể cung cấp) – user72150

2

Để trả lời tất cả các câu hỏi của bạn:

Đây có phải là một giải pháp khả thi cho cuộc tấn công WAITFOR?

Không. Chỉ cần thêm - vào chuỗi tấn công và nó sẽ bỏ qua sửa lỗi của bạn.

Google có bảo vệ chống lại các lỗ hổng tương tự khác không?

No. Xem ở trên.

Tôi nghĩ tùy chọn tốt nhất sẽ đòi hỏi phải sử dụng câu lệnh đã chuẩn bị. Nhiều công việc hơn, nhưng ít bị tổn thương hơn.

Có. Bạn không tự sửa lỗi SQL. Bạn sử dụng những gì đã tồn tại và bạn sử dụng nó đúng, nghĩa là, bằng cách tham số bất kỳ phần động nào của truy vấn của bạn.

Một giải pháp nhỏ hơn là thoát khỏi bất kỳ chuỗi nào sẽ được chèn vào truy vấn của bạn, tuy nhiên, bạn sẽ quên một ngày và bạn chỉ cần một để bị tấn công.

0

Mọi người khác đã đóng đinh này (parameterize!) Nhưng chỉ để chạm vào một vài điểm ở đây:

  • Đây có phải là một giải pháp khả thi cho cuộc tấn công WAITFOR?
  • Ứng dụng có chống lại các lỗ hổng tương tự khác không?

Không, không. Mẹo WAITFOR rất có thể chỉ được sử dụng để 'đánh hơi' cho lỗ hổng; một khi họ đã tìm thấy trang dễ bị tổn thương, có rất nhiều thứ họ có thể làm mà không có DDL hoặc (các phần không phải là phần của DML) của DML. Ví dụ: hãy nghĩ xem liệu họ có vượt qua những điều sau đây như last_name hay không

' UNION ALL SELECT username, password FROM adminusers WHERE 'A'='A 

Ngay cả sau khi bạn thêm AND 1 = 1, bạn vẫn bị hosed. Trong hầu hết các cơ sở dữ liệu, có rất nhiều thứ độc hại bạn có thể thực hiện chỉ với quyền truy cập SELECT ...

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