2010-02-06 123 views
6

Tôi đã thực hiện một số đọc về bảo mật các ứng dụng PHP, và dường như với tôi rằng mysqli_real_escape_string là chức năng chính xác để sử dụng khi chèn dữ liệu vào bảng MySQL vì addslashes có thể gây ra một số điều kỳ lạ xảy ra kẻ tấn công thông minh. Đúng?Htmlentities vs addslashes vs mysqli_real_escape_string

Tuy nhiên, có một điều khiến tôi khó hiểu. Tôi dường như nhớ rằng việc được thông báo addslashes tốt hơn htmlentities khi lặp lại dữ liệu do người dùng nhập lại cho người dùng để bảo vệ dữ liệu của họ, nhưng có vẻ như addslashes là người có lỗ hổng. Điều này đúng hay tôi nhớ không chính xác?

Trả lời

5

Có các ngữ cảnh khác nhau cho dữ liệu của bạn. Ngữ cảnh chèn dữ liệu vào cơ sở dữ liệu cần phải được thoát khác với ngữ cảnh hiển thị html/xml hoặc thậm chí là thông báo email.

Dữ liệu thoát vào một db sẽ không được chấp nhận trong tất cả mã mới có lợi cho các câu lệnh được chuẩn bị. Bất cứ ai nói với bạn bằng cách khác là làm bạn một sự bất hòa lớn.

Dữ liệu thoát vào trình duyệt cần phải được thoát theo một số cách khác nhau tùy thuộc vào mục tiêu. Đôi khi htmlspecialchars là đủ, đôi khi bạn cần phải sử dụng htmlentities. Đôi khi bạn cần các thực thể dạng số. Đó là một chủ đề bạn nên làm một số nghiên cứu về để biết tất cả các sắc thái.

Quy tắc chung tôi đang sống là xác thực (không lọc, từ chối nếu không chính xác) đầu vào & đầu ra thoát (dựa trên ngữ cảnh).

+0

Tốc độ cao, các câu lệnh chuẩn bị chỉ tốt hơn nếu bạn đang sử dụng truy vấn đã chuẩn bị nhiều lần trong một tập lệnh duy nhất. Nếu không, bạn đang thực hiện hai chuyến đi khứ hồi tới máy chủ, một lần để chuẩn bị và một lần để thực hiện. Nếu bạn đã sử dụng mã tự động đảm bảo xác thực đầu vào, tôi không biết tại sao các câu lệnh chuẩn bị tốt hơn. tài liệu mysql bao gồm điều này. http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html Nếu tôi sai (có thể và có thể xảy ra), hãy cho tôi biết lý do. –

+2

Greets Mike. Tôi đã nhìn thấy đối số truy cập này quá nhiều lần và tôi nghĩ rằng nó cần phải được đặt để nghỉ ngơi. Hãy hiểu, rằng tôi không đồng ý với những gì bạn đã nói. Tuy nhiên, tôi không đồng ý với lời khuyên này trong một diễn đàn như thế này. Tôi nghĩ rằng an toàn nên là một ưu tiên cao hơn so với hiệu suất dễ bị lỗi trong trường hợp này. OP không phàn nàn về trang web của mình, mà là thiếu định nghĩa rõ ràng giữa các kỹ thuật thoát khác nhau. Bạn có đồng ý rằng ai đó bắt đầu cuộc hành trình này nên đi theo con đường an toàn hơn không? –

+0

Tôi đồng ý hoàn toàn. Tôi đã hỏi về hiệu suất cho bản thân mình bởi vì tôi không chắc chắn về câu trả lời. Tôi không nói rõ điều đó. –

0

Bạn cũng có thể sử dụng số PDO libs mà hầu hết các lần thoát cho bạn, trong trường hợp bạn có thể sử dụng PHP5 trên máy chủ.

Hồi âm lại, cá nhân tôi thích htmlspecialchars hơn, nhưng người ta có thể sửa tôi

11

Chúng là các công cụ khác nhau cho các mục đích khác nhau.

mysqli_real_escape_string làm cho dữ liệu an toàn để chèn vào MySQL (nhưng các truy vấn được tham số tốt hơn).

htmlentities làm cho dữ liệu an toàn cho xuất ra thành một tài liệu HTML

addslashes làm cho an toàn trong một vài tình huống khác dữ liệu, nhưng không đủ để MySQL

+0

Bạn nên đăng một trường hợp trong đó addslashes() không thành công và mysql_real_escape_string() dừng nó lại. Tôi không nghĩ rằng bạn có thể, nhưng đây là một truy vấn mà cả hai đều thất bại: mysql_query ("select * from user id =". $ _ GET [id]); – rook

+0

bổ sung giả định tất cả mọi thứ là 8bit. mysql_real_escape_string lấy mã hóa ký tự vào tài khoản khi thực hiện mã hóa của nó. Bằng chứng: http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string –

+0

@Eric, đã được sửa. Hãy thử khai thác của mình trên một hệ thống được vá đầy đủ, nó sẽ thất bại. – rook

0

có, sử dụng mysqli_real_escape_string hoặc một thư viện như PDO trên tất cả các người sử dụng đầu vào. Khi lặp lại, tôi sử dụng htmlentities với ENT_QUOTES làm tham số thứ hai, vì nó thoát tất cả các ký tự có thể áp dụng cho các thực thể html của chúng, bao gồm cả dấu ngoặc kép.

0

Lưu ý: Bạn nên tránh sử dụng htmlentities() trong tài liệu được mã hóa UTF-8.Xem:

Chú ý đến (trích dẫn từ phpwact.org):

Với các trình duyệt web hiện đại và hỗ trợ widespead cho UTF-8, bạn don' t cần htmlentities vì ​​tất cả các ký tự này có thể được biểu diễn trực tiếp trong UTF-8. Quan trọng hơn, trong chung, chỉ các trình duyệt mới hỗ trợ các ký tự đặc biệt của HTML - một văn bản bình thường trình chỉnh sửa, chẳng hạn, không biết về các đối tượng HTML . Tùy thuộc vào những gì bạn đang làm, sử dụng htmlentities có thể giảm khả năng của các hệ thống khác thành "tiêu thụ" nội dung của bạn.

Ngoài ra (không được xác nhận nhưng có vẻ hợp lý - từ anon bình luận ở đây), thực thể ký tự (những thứ như thế »hay -) không hoạt động khi một tài liệu được phục vụ như application/xml + xhtml (trừ khi bạn xác định chúng). Tuy nhiên, bạn vẫn có thể lấy đi bằng biểu mẫu dạng số.

+1

Việc sử dụng phổ biến của 'htmlentities()' không hiển thị các ký tự "lạ" mà là tránh văn bản nguy hiểm có thể được phân tích cú pháp làm đánh dấu và điều này không liên quan gì đến mã hóa. –

+0

Tránh văn bản có thể nguy hiểm có thể đạt được với htmlspecialchars(). htmlentities() có chi phí chuyển đổi các ký tự 'an toàn' và nó trình bày các vấn đề khác mà tôi đã đề cập trước đó. – Dor

0

Một giải pháp thú vị cho PHP 5.2 trở lên là sử dụng phần mở rộng lọc: http://www.php.net/manual/en/book.filter.php

Nó cho phép bạn xác nhận và khử trùng đầu vào người dùng. Có rất nhiều bộ lọc tích hợp sẵn có và chúng có thể được kết hợp với cờ để tinh chỉnh hành vi của chúng. Ngoài ra bộ lọc hese cũng có thể được sử dụng để xác nhận/khử trùng ints, float, email, biểu thức chính quy cụ thể.

Cá nhân tôi đã bắt đầu sử dụng chúng trong các dự án của mình để xác thực biểu mẫu và xuất dữ liệu do người dùng nhập và tôi rất vui vì tôi đã làm. Mặc dù, khi tôi chèn các giá trị trong cơ sở dữ liệu MySQL, tôi sử dụng các truy vấn đã chuẩn bị để tăng cường bảo mật. Các giải pháp này cùng nhau có thể giúp tránh được hầu hết các lần tiêm SQL và các cuộc tấn công kiểu XSS.

0

Bạn không thể có một chức năng "thoát" và mong muốn nó hoạt động mọi lúc. Có những cuộc tấn công khác nhau đòi hỏi thói quen vệ sinh cụ thể. Cách duy nhất để hiểu khái niệm này là viết một số mã dễ bị tổn thương và sau đó khai thác nó. Viết mã khai thác là rất quan trọng đối với sự hiểu biết của bất kỳ hệ thống bảo mật nào.

Ví dụ truy vấn này là dễ bị SQL injection:

$host=htmlspecialchars($_GET[host],ENT_QUOTES); 
$name=htmlspecialchars($_GET[name],ENT_QUOTES); 
mysql_query("select * from user where Host='$host' and Name='$name' "); 

Khai thác: http://localhost/sqli_test.php?host= \ & name =% 20sleep (20) -% 201

Chức năng thoát tốt nhất cho mysql được mysqli_real_escape_string() nhưng điều này có thể không thành công:

mysql_query("select * from user where id=".mysqli_real_escape_string($_GET[id])); 

khai thác: http://localhost/sqli_test.php?id=1%20or%20sleep(20)

Trong thực tế, cách tốt nhất để chăm sóc tiêm sql không gọi là một chức năng thoát, nó sử dụng các yêu cầu parametrized ADODB cho tiêm sql. Sử dụng htmlspecialcahrs ($ var, ENT_QUTOES) cho XSS.Đọc số OWASP top 10 vì có rất nhiều thứ có thể sai với bảo mật ứng dụng web.