Dừng lại!
Bạn đang mắc lỗi ở đây. Ồ, không, bạn đã chọn đúng các hàm PHP để làm cho dữ liệu của bạn an toàn hơn một chút. Tốt rồi. Lỗi của bạn là theo thứ tự các hoạt động , và cách sử dụng các chức năng này.
Điều quan trọng là phải hiểu sự khác biệt giữa vệ sinh và xác thực dữ liệu người dùng, thoát dữ liệu để lưu trữ và thoát dữ liệu để trình bày.
Vệ sinh và xác thực dữ liệu người dùng
Khi người dùng gửi dữ liệu, bạn cần đảm bảo rằng họ đã cung cấp thứ bạn mong đợi.
Vệ sinh và lọc
Ví dụ: nếu bạn mong đợi một số, hãy đảm bảo dữ liệu đã gửi là một số . Bạn cũng có thể truyền dữ liệu người dùng thành các loại khác. Mọi thứ được gửi ban đầu được xử lý như một chuỗi, do đó, việc buộc dữ liệu số đã biết thành số nguyên hoặc số float làm cho việc khử trùng nhanh và không gây đau đớn.
Còn các trường văn bản dạng tự do và textareas thì sao? Bạn cần đảm bảo rằng không có gì bất ngờ trong các lĩnh vực đó. Chủ yếu, bạn cần đảm bảo rằng các trường không có bất kỳ nội dung HTML nào không thực sự chứa HTML. Có hai cách bạn có thể đối phó với vấn đề này.
Trước tiên, bạn có thể thử thoát khỏi đầu vào HTML với htmlspecialchars
. Bạn không nên sử dụng htmlentities
để vô hiệu hóa HTML, vì nó cũng sẽ thực hiện mã hóa các ký tự có dấu và các ký tự khác mà nó nghĩ cũng cần phải được mã hóa.
Thứ hai, bạn có thể thử xóa bất kỳ HTML nào có thể. strip_tags
là nhanh chóng và dễ dàng, nhưng cũng cẩu thả. Bộ lọc HTML thực hiện công việc kỹ lưỡng hơn nhiều về cả việc loại bỏ tất cả HTML và cũng cho phép một danh sách trắng các thẻ và thuộc tính chọn lọc thông qua.
Các phiên bản PHP hiện đại xuất xưởng với phần mở rộng bộ lọc , cung cấp một cách toàn diện để vệ sinh đầu vào của người dùng.
Thẩm định
Đảm bảo rằng dữ liệu đã gửi không có nội dung bất ngờ chỉ là một nửa của công việc. Bạn cũng cần thử và đảm bảo rằng dữ liệu được gửi có chứa các giá trị mà bạn thực sự có thể làm việc với.
Nếu bạn đang mong đợi một số trong khoảng từ 1 đến 10, bạn cần kiểm tra giá trị đó. Nếu bạn đang sử dụng một trong những đầu vào số ưa thích thời đại HTML5 mới với công cụ quay vòng và các bước, hãy đảm bảo rằng dữ liệu đã gửi phù hợp với bước này.
Nếu dữ liệu đó đến từ một menu thả xuống, hãy đảm bảo rằng giá trị được gửi là một giá trị xuất hiện trong menu.
Điều gì về đầu vào văn bản đáp ứng các nhu cầu khác? Ví dụ: đầu vào ngày phải được xác thực thông qua strtotime
hoặc lớp DateTime . Ngày đã cho phải nằm trong khoảng bạn mong đợi. Địa chỉ email thì sao? Tiện ích mở rộng bộ lọc được đề cập trước đây có thể kiểm tra xem một địa chỉ có được định dạng tốt hay không, mặc dù tôi là người hâm mộ thư viện is_email .
Điều này cũng đúng với tất cả các điều khiển biểu mẫu khác. Có nút radio? Xác nhận đối với danh sách. Có hộp kiểm tra? Xác nhận đối với danh sách. Có một tập tin tải lên? Đảm bảo tệp thuộc loại dự kiến và coi tên tệp như dữ liệu người dùng chưa được lọc.
Mỗi trình duyệt hiện đại đi kèm với một bộ đầy đủ các công cụ dành cho nhà phát triển được tích hợp ngay, điều này khiến cho mọi người thao túng biểu mẫu của bạn trở nên tầm thường. Mã của bạn nên cho rằng người dùng đã loại bỏ hoàn toàn tất cả các hạn chế phía máy khách đối với nội dung biểu mẫu !
Thoát dữ liệu để lưu trữ
Bây giờ bạn đã chắc chắn rằng dữ liệu của bạn ở định dạng mong đợi và chỉ chứa các giá trị dự kiến, bạn cần lo lắng về việc lưu giữ dữ liệu đó để lưu trữ.
Mỗi cơ chế lưu trữ dữ liệu duy nhất có một cách cụ thể để đảm bảo dữ liệu được thoát và mã hóa chính xác. Nếu bạn đang xây dựng SQL, thì cách được chấp nhận để truyền dữ liệu trong các truy vấn là thông qua các câu lệnh được chuẩn bị với trình giữ chỗ .
Một trong những cách tốt hơn để làm việc với hầu hết các cơ sở dữ liệu SQL trong PHP là phần mở rộng PDO . Nó tuân theo mô hình chung là chuẩn bị một câu lệnh , ràng buộc các biến với câu lệnh , sau đó gửi câu lệnh và biến đến máy chủ . Nếu bạn chưa từng làm việc với PDO trước đây thì đây là một hướng dẫn khá tốt về định hướng MySQL .
Một số cơ sở dữ liệu SQL có các phần mở rộng đặc biệt của riêng chúng trong PHP, bao gồm SQL Server , PostgreSQL và SQLite 3 . Mỗi tiện ích mở rộng này đã chuẩn bị hỗ trợ câu lệnh hoạt động theo cùng kiểu chuẩn bị ràng buộc-thực thi như PDO. Đôi khi bạn có thể cần sử dụng các tiện ích mở rộng này thay vì PDO để hỗ trợ các tính năng hoặc hành vi không chuẩn.
MySQL cũng có các phần mở rộng PHP riêng. Hai trong số họ, trên thực tế. Bạn chỉ muốn sử dụng một cái gọi là mysqli . Phần mở rộng "mysql" cũ đã không còn được sử dụng và không an toàn hoặc lành mạnh để sử dụng trong thời kỳ hiện đại.
Cá nhân tôi không phải là fan hâm mộ của mysqli. Cách nó thực hiện ràng buộc thay đổi trên các báo cáo đã chuẩn bị là không linh hoạt và có thể là một nỗi đau để sử dụng. Khi nghi ngờ, sử dụng PDO thay thế.
Nếu bạn không sử dụng cơ sở dữ liệu SQL để lưu trữ dữ liệu của mình, hãy kiểm tra tài liệu cho giao diện cơ sở dữ liệu bạn đang sử dụng để xác định cách truyền dữ liệu qua dữ liệu một cách an toàn.
Khi có thể, hãy đảm bảo rằng cơ sở dữ liệu của bạn lưu trữ dữ liệu của bạn ở định dạng phù hợp. Lưu số trong các trường số. Lưu trữ ngày trong các trường ngày. Lưu trữ tiền trong trường thập phân, không phải trường dấu phẩy động. Xem lại tài liệu được cung cấp bởi cơ sở dữ liệu của bạn về cách lưu trữ đúng các loại dữ liệu khác nhau.
Thoát dữ liệu để trình bày
Mỗi khi bạn hiển thị dữ liệu cho người dùng, bạn phải đảm bảo rằng dữ liệu được thoát an toàn, trừ khi bạn biết rằng nó không nên được thoát.
Khi phát HTML, bạn hầu như luôn luôn chuyển bất kỳ dữ liệu nào ban đầu được cung cấp bởi người dùng htmlspecialchars
. Trên thực tế, lần duy nhất bạn không nên làm điều này là khi bạn biết rằng người dùng đã cung cấp HTML và bạn biết rằng nó đã được khử trùng bằng cách sử dụng danh sách trắng.
Đôi khi bạn cần tạo một số Javascript bằng PHP. Javascript không có các quy tắc thoát giống như HTML! Một cách an toàn để cung cấp các giá trị do người dùng cung cấp cho Javascript thông qua PHP là thông qua json_encode
.
Và hơn thế nữa
Có nhiều sắc thái hơn để xác nhận dữ liệu.
Ví dụ, mã hóa bộ ký tự có thể là một cái bẫy lớn . Ứng dụng của bạn nên tuân theo các thông lệ được nêu trong " UTF-8 suốt ". Có những cuộc tấn công giả định có thể xảy ra khi bạn coi dữ liệu chuỗi là tập ký tự sai.
Trước đó tôi đã đề cập đến các công cụ gỡ lỗi trình duyệt. Những công cụ này cũng có thể được sử dụng để thao tác dữ liệu cookie. Cookies nên được coi là đầu vào không đáng tin cậy của người dùng .
Xác thực và thoát dữ liệu chỉ là một khía cạnh của bảo mật ứng dụng web. Bạn nên tự biết về các phương pháp tấn công ứng dụng web để có thể xây dựng hệ thống phòng thủ chống lại chúng.