2012-11-28 27 views
9

Như tiêu đề gợi ý, tôi muốn biết liệu mã này có dễ bị tấn công với SQL Injection không? Và nếu vậy, có cách nào tốt hơn, an toàn hơn, để đạt được điều tương tự không?Mã Python này có dễ bị tấn công SQL không? (SQLite3)

def add(table,*args): 
    statement="INSERT INTO %s VALUES %s" % (table,args) 
    cursor.execute(statement) 
+1

Tôi khuyên bạn nên đọc những gì về SQL injection. Nó sẽ làm cho nó rất rõ ràng. –

Trả lời

21

Có, đúng vậy. Sử dụng một cái gì đó như thế này để ngăn chặn nó:

cursor.execute("INSERT INTO table VALUES ?", args) 

Lưu ý rằng bạn không thể nhập bảng như thế này. Lý tưởng nhất là bảng nên được mã hóa cứng, trong mọi trường hợp, nó phải đến từ đầu vào của người dùng dưới bất kỳ hình thức nào. Bạn có thể sử dụng một chuỗi tương tự như những gì bạn đã làm cho bảng, nhưng bạn nên chắc chắn 100% chắc chắn rằng người dùng không thể thay đổi nó bằng cách nào đó ... Xem Can I use parameters for the table name in sqlite3? để biết thêm chi tiết.

Về cơ bản, bạn muốn đặt các tham số trong lệnh con trỏ, vì nó sẽ đảm bảo làm cho cơ sở dữ liệu dữ liệu an toàn. Với lệnh đầu tiên của bạn, nó sẽ là tương đối dễ dàng để thực hiện một đặc biệt table hoặc args mà đặt một cái gì đó vào mã SQL của bạn mà không được an toàn. Xem python pages và tham chiếu http://xkcd.com/327/. Cụ thể, các trang python trích dẫn:

Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack (see http://xkcd.com/327/ for humorous example of what can go wrong).

Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.)

Về cơ bản, ai đó có thể thiết lập một args rằng thực hiện lệnh khác, một cái gì đó như thế này:

args="name; DELETE table" 

Sử dụng cursor.execute sẽ nhồi giá trị nhất định, do đó đối số có thể được liệt kê, và khi bạn thực hiện một truy vấn trên đó, đó chính là điều bạn sẽ nhận ra. XKCD giải thích điều này một cách hài hước.

enter image description here

+0

Cảm ơn. Bạn có thể mở rộng một chút là tại sao nó dễ bị tổn thương không? – Sheldon

+1

Nó có thể là yên tĩnh rõ ràng, nhưng chỉ để được an toàn: Làm điều này cho tất cả các báo cáo, không chỉ INSERT. Một câu lệnh SELECT cũng dễ bị tổn thương. –

+0

@PearsonArtPhoto Tôi nhận được "TypeError: chức năng mất nhiều nhất 2 đối số (3 đã cho)" – Sheldon

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