2008-09-19 39 views
8

Tôi có một số mã sử dụng truy vấn được tham số hóa để ngăn chặn việc tiêm, nhưng tôi cũng cần có khả năng tự động xây dựng truy vấn bất kể cấu trúc của bảng. Cách thích hợp để làm điều này là gì?Các cột SQL được tham số hóa?

Dưới đây là một ví dụ, giả sử tôi có một bảng có cột Tên, Địa chỉ, Điện thoại. Tôi có một trang web nơi tôi chạy Hiển thị các cột và điền một menu thả xuống chọn với các tùy chọn đó.

Tiếp theo, tôi có một hộp văn bản được gọi là Tìm kiếm. Hộp văn bản này được sử dụng làm tham số.

Hiện nay mã của tôi trông giống như sau:

 
result = pquery('SELECT * FROM contacts WHERE `' + escape(column) + '`=?', search); 

tôi nhận được một cảm giác mảng nhầy khỏi nó mặc dù. Lý do tôi đang sử dụng truy vấn được tham số hóa là tránh sử dụng escape. Ngoài ra, escape có thể không được thiết kế để thoát tên cột.

Làm cách nào để đảm bảo cách này hoạt động theo cách tôi dự định?

Chỉnh sửa: Lý do tôi yêu cầu truy vấn động là lược đồ có thể định cấu hình người dùng và tôi sẽ không sửa chữa bất kỳ thứ gì được mã hóa cứng.

Trả lời

6

Thay vì chuyển tên cột, chỉ cần chuyển mã định danh mà bạn mã sẽ dịch sang tên cột bằng cách sử dụng bảng được mã cứng. Điều này có nghĩa là bạn không cần phải lo lắng về dữ liệu độc hại đang được truyền, vì tất cả dữ liệu đều được dịch hợp pháp hoặc được biết là không hợp lệ. Mã Psudoish:

@columns = qw/Name Address Telephone/; 
if ($columns[$param]) { 
    $query = "select * from contacts where $columns[$param] = ?"; 
} else { 
    die "Invalid column!"; 
} 

run_sql($query, $search); 
+0

Mã hóa cứng không phải là một lựa chọn cho tôi, cảm ơn bạn đã đề xuất! – Martin

+0

Điểm của tôi không phải là mã hóa các tên cột mà không phải để chuyển chúng từ giao diện. Bạn có thể nhận danh sách các cột động và vẫn sử dụng cùng một giải pháp ở trên. Chỉ cần không làm cho phần tên cột của dữ liệu được truyền đi - điều đó sẽ bảo vệ bạn khỏi bất kỳ sự tiêm SQL nào. – zigdon

+0

+1 Có, tôi muốn nói: cho phép người dùng nhập dữ liệu, nhưng không cho phép người dùng cung cấp mã. –

0

Bí quyết là tự tin trong việc thoát và xác thực thói quen của bạn. Tôi sử dụng chức năng thoát khỏi SQL của riêng tôi mà quá tải cho các loại chữ khác nhau. Không nơi nào tôi chèn các biểu thức (trái ngược với các giá trị chữ được trích dẫn) trực tiếp từ đầu vào của người dùng.

Tuy nhiên, có thể thực hiện được, tôi khuyên bạn nên sử dụng chức năng — và chức năng nghiêm ngặt — để xác thực tên cột. Cho phép nó chỉ chấp nhận một số nhận dạng duy nhất, chẳng hạn như

 
/^\w[\w\d_]*$/ 

Bạn sẽ phải dựa vào các giả định bạn có thể tạo về tên cột của riêng bạn.

0

Tôi sử dụng ADO.NET và việc sử dụng các lệnh SQL và SQLParameters cho các lệnh đó sẽ xử lý vấn đề Escape. Vì vậy, nếu bạn đang ở trong một môi trường Microsoft-công cụ là tốt, tôi có thể nói rằng tôi sử dụng này rất sucesfully để xây dựng SQL năng động và chưa bảo vệ các thông số của tôi

best of luck

0

Hãy cột dựa trên kết quả của một truy vấn khác đến một bảng liệt kê các giá trị lược đồ có thể có. Trong truy vấn thứ hai đó, bạn có thể mã hóa lựa chọn thành tên cột được sử dụng để định nghĩa lược đồ. nếu không có hàng nào được trả về thì cột được nhập không hợp lệ.

0

Trong SQL chuẩn, bạn kèm theo số nhận dạng được phân tách trong dấu ngoặc kép.Điều này có nghĩa rằng:

SELECT * FROM "SomeTable" WHERE "SomeColumn" = ? 

sẽ lựa chọn từ một bảng gọi là SomeTable với giá trị vốn hóa hiển thị (không phải là một phiên bản chữ-chuyển đổi tên), và sẽ áp dụng một điều kiện để một cột gọi là SomeColumn với giá trị vốn hóa hiển thị.

Bản thân nó không hữu ích lắm, nhưng ... nếu bạn có thể áp dụng kỹ thuật escape() với dấu ngoặc kép cho các tên được nhập thông qua biểu mẫu web của bạn, thì bạn có thể xây dựng truy vấn một cách hợp lý một cách tự tin.

Tất nhiên, bạn nói rằng bạn muốn tránh sử dụng thoát - và thực sự bạn không phải sử dụng nó trên các thông số mà bạn cung cấp? người giữ chỗ. Nhưng khi bạn đang đưa dữ liệu do người dùng cung cấp vào truy vấn, bạn cần tự bảo vệ mình khỏi những người độc hại.

DBMS khác nhau có các cách khác nhau để cung cấp số nhận dạng được phân tách. Ví dụ, MS SQL Server dường như sử dụng các dấu ngoặc vuông [SomeTable] thay vì dấu ngoặc kép.

0

Tên cột trong một số cơ sở dữ liệu có thể chứa dấu cách, có nghĩa là bạn phải báo tên cột, nhưng nếu cơ sở dữ liệu của bạn không chứa cột như vậy, chỉ cần chạy tên cột thông qua biểu thức chính quy hoặc một số loại kiểm tra trước khi nối vào SQL:

if ($column !~ /^\w+$/) { 
    die "Bad column name [$column]"; 
} 
Các vấn đề liên quan