2011-06-28 26 views
32

Các phương pháp hay nhất để giảm thiểu các cuộc tấn công SQL injection khi sử dụng SQLAlchemy là gì?SQLAlchemy + SQL Injection

+24

Sử dụng SQLAlchemy * là * phương pháp hay nhất. :-) –

Trả lời

31

Nếu bạn có bất kỳ nhân vật "đặc biệt" (ví dụ như dấu chấm phẩy hoặc dấu nháy) trong dữ liệu của bạn, họ sẽ được tự động trích dẫn cho bạn bởi đối tượng SQLEngine, vì vậy bạn không cần phải lo lắng về trích dẫn. Điều này cũng có nghĩa là trừ khi bạn cố ý bỏ qua các cơ chế trích dẫn của SQLAlchemy SQLAlchemy, về cơ bản là không thể.

[mỗi http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html]

+16

Câu trả lời cho biết rằng trích dẫn đến từ tài liệu "", khi nó không: nó dường như đến từ [hướng dẫn] (http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html) không liên kết với SQLAlchemy. Thứ hai, báo giá nằm trong ngữ cảnh một phần của API SQLAlchemy sẽ xử lý một cách chính xác việc thoát, bằng cách sử dụng một ví dụ xử lý việc thoát. Tuy nhiên, bạn vẫn có thể sử dụng 'execute()' hoặc dữ liệu theo nghĩa đen khác sẽ không được SQLAlchemy thoát. Có, trong các trường hợp MOST SQLAlchemy sẽ tự động thoát, nhưng nếu bạn đang sử dụng chữ hoặc SQL thô, bạn vẫn có thể tự bắn mình vào chân. –

51

TLDR: Tránh SQL liệu càng nhiều càng tốt.

Câu trả lời được chấp nhận là lười và không chính xác. Phương thức lọc chấp nhận SQL thô và nếu được sử dụng theo cách đó, hoàn toàn dễ bị tấn công SQL injection. Ví dụ, nếu bạn đã chấp nhận một giá trị từ một url và kết hợp nó với sql liệu trong bộ lọc, bạn đang mở để tấn công:

session.query(MyClass).filter("foo={}".format(getArgs['val']))

sử dụng đoạn code trên và url dưới đây, bạn sẽ được tiêm SQL vào câu lệnh lọc của bạn. Đoạn mã trên sẽ trả về tất cả các hàng trong cơ sở dữ liệu của bạn.

http://domain.com/?val=2%20or%201%20=%201

+4

"trừ khi bạn cố tình bỏ qua các cơ chế trích dẫn của SQLAlchemy ...Vì vậy, không, câu trả lời ở trên là không chính xác – Johnston

+12

Tôi không đồng ý rằng bạn có thể chuyển sql thô vào phương pháp lọc là một phần của sqlalchemy, không phải một số hack xung quanh ... – Mike

+2

Nếu tôi phải nhận đầu vào của người dùng cho một bộ lọc, cách chính xác để đảm bảo người dùng không nhập SQL thô để thả bảng hoặc bất kỳ hành vi không mong muốn nào khác là –

3

Để thêm vào @Tendrid answer. Tôi đã làm một cuộc điều tra nhỏ bằng cách sử dụng cách tiếp cận ngây thơ. Phương thức filter có đối số là *criterion, một số phương thức truy vấn ORM khác có đối số tương tự.

Trong trường hợp filter phương thức *criterion đối số kết thúc bằng cách chuyển thành _literal_as_text, trong trường hợp chuỗi - đánh dấu là an toàn sql (vui lòng sửa tôi nếu tôi sai). Do đó nó làm cho nó không an toàn.

Dưới đây là kết quả của ORM Query class phương pháp điều tra với *criterion luận:

filter - uses _literal_as_text (NOT SAFE) 
having - uses _literal_as_text (NOT SAFE) 

distinct - uses _literal_as_label_reference (NOT SAFE) 
group_by - uses _literal_as_label_reference (NOT SAFE) 
order_by - uses _literal_as_label_reference (NOT SAFE) 

join  - uses model attributes to resolve relation (SAFE) 

Ví dụ về các phương pháp có thể missuses (để giữ cho nó đơn giản, chuỗi định dạng là bỏ qua):

db.session.query(User.login).group_by('login').having('count(id) > 4; select name from roles').all() 
db.session.query(User.login).distinct('name) name from roles /*').order_by('*/').all() 
db.session.query(User.login).order_by('users_login; select name from roles').all() 
db.session.query(User.login).group_by('login union select name from roles').all() 

Lưu ý rằng các phương pháp này chỉ không an toàn nếu chuỗi ký tự được truyền qua.