5 mẹo hữu ích tạo ra ứng dụng PHP bảo mật

PHP là một trong những ngôn ngữ lập trình phổ biến nhất cho lập trình web. Đôi khi một ngôn ngữ với tính năng thân thiện có thể giúp lập trình viên rất nhiều nhưng cũng có rất nhiều lỗ hổng tạo ra rào cản trong việc phát triển. Trong bài hướng dẫn sau, chúng ta hãy cùng xem 5 mẹo giúp bạn tránh một vài lỗi trong việc lập trình PHP.

1. Sử dụng hợp lí Error Reporting

Trong quá trình phát triển, cảnh báo lỗi là công cụ tốt nhất của bạn. Các cảnh báo lỗi này giúp bạn tìm ra những lỗi chính tả trong biến, phát hiện hàm sử dụng sai và nhiều hơn thế. Tuy nhiên, khi trang web của bạn đã được trực tuyến thì các thông báo lỗi lại trở thành “kẻ thù” vì nó có thể cho người dùng biết rất nhiều thông tin về trang web (phần mềm bạn sử dụng, cấu trúc folder…).

Khi trang web đã đi vào hoạt động, bạn nên đảm bảo rằng đã ẩn tất cả các thông báo lỗi. Điều đó có thể thực hiện bằng cách sử dụng hàm đơn giản sau:

1
error_reporting(0);

Nếu chức năng nào đó hoạt động không đúng, bạn vẫn muốn và cần biết về nó. Vì vậy bạn nên luôn đảm bảo rằng bạn đã log lại lỗi xảy ra vào một file được bảo vệ với hàm set_error_handler.

errorlog

2. Vô hiệu hóa những “tính năng yếu” của PHP

Từ những ngày đầu tiên, nhà thiết kế PHP luôn thêm vào những tính năng giúp việc phát triển dễ dàng hơn. Một vài tính năng hữu ích có thể gây ra các hệ quả không lường trước được. Những tính năng này cho phép kiểm duyệt dữ liệu trở nên khó khăn và tạo ra những lỗi hệ thống. Một trong những điều đầu tiên bạn nên làm khi bắt đầu phát triển là vô hiệu hóa những tính năng này.

Lưu ý: Việc vô hiệu hóa “tính năng yếu” hay không phụ thuộc vào host của bạn. Nếu bạn phát triển trên máy tính riêng hay các những môi trường cục bộ tương tự, chúng có thể bắt buộc phải bật. Một vài tính năng sẽ được loại bỏ trong bản PHP6.

Register Globals (register_globals)

register_globals giúp tăng tốc việc phát triển ứng dụng. Lấy ví dụ URL: http://yoursite.tld/index.php?var=1 bao gồm một truy vấn string. register_globals cho phép chúng ta truy cập vào giá trị với $var thay vì $_GET[‘var’] một cách tự động. Điều này nghe có vẻ hữu ích với bạn nhưng không may tất cả các biến trong code đều có thuộc tính này và chúng ta có thể dễ dàng truy cập vào ứng dụng PHP không có bảo vệ. Đoạn code dưới đây là một ví dụ mà bạn thường thấy trong PHP script:

if( !empty( $_POST['username'] ) && $_POST['username'] == 'test' && !empty( $_POST['password'] ) && $_POST['password'] == "test123" )
{
    $access = true;
}

Thật không may chúng ta không thể vô hiệu hóa register_globals từ phía script nhưng chúng ta có thể sử dụng tệp tin .htaccess để làm điều này. Một vài host cho phép bạn chứa file php.ini trên máy chủ. Nếu ứng dụng sử dụng register_globals, người dùng sẽ có thể đặt access=1 vào một truy vấn string và sẽ có thể truy cập vào bất cứ script nào đang chạy.

Vô hiệu hóa với .htaccess

php_flag register_globals 0

Vô hiệu hóa với php.ini

register_globals = Off

Lưu ý: Nếu bạn sử dụng file php.ini không phù hợp với toàn bộ máy chủ, bạn cần bổ sung khai báo ở mỗi thư mục phụ có PHP.

var

Magic Quotes (magic_quotes_gpc, magic_quotes_runtime, magic_quotes_sybase)

Magic Quotes là một tính năng giúp lập trình viên tránh rắc rối khi sử dụng addslashes() và những tính năng bảo mật tương tự trong code. Có ít nhất 3 vấn đề với Magic Quotes. Một vấn đề xảy ra khi cả Magic Quotes và addslashes() đều được sử dụng. Trong trường hợp này, nếu bạn có thể kết thúc chuỗi với nhiều dấu sổ/ có thể sẽ gây ra lỗi. Vấn đề thứ hai là nếu bạn bật Magic Quotes nhưng nó không hoạt động. Điều này khiến tất cả dữ liệu đầu vào đều không được kiểm tra. Vấn đề thứ ba là Magic Quotes sử dụng dấu sổ đơn hoặc kép nhưng nếu bạn sử dụng một database engine, có rất nhiều kí tự đặc biệt cần được sử dụng. Vì vậy bạn nên vô hiệu hóa tính năng này và sử dụng một biến phù hợp.

Vô hiệu hóa với .htaccess

php_flag magic_quotes_gpc 0 php_flag magic_quotes_runtime 0

Vô hiệu hóa với php.ini

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off

Lưu ý: Nếu bạn sử dụng file php.ini không phù hợp với toàn bộ máy chủ, bạn cần bổ sung khai báo ở mỗi thư mục phụ có PHP.

3. Kiểm tra đầu vào

Với một ứng dụng, bạn phải chắc chắn loại dữ liệu nào sẽ được đưa vào xử lý. Vì vậy cách tốt nhất để bảo vệ là đảm bảo người dùng chỉ có thể nhập vào dữ liệu phù hợp. Ví dụ, bạn muốn tạo ra một ứng dụng liệt kê danh sách sinh nhật người dùng và cho phép người dùng thêm vào sinh nhật mới. Bạn muốn chấp nhận dữ liệu tháng là một số từ 1 đến 12, ngày là 1 đến 31 và năm có định dạng YYYY. Hãy xem ví dụ dưới đây:

if ( ! preg_match( "/^[0-9]{1,2}$/", $_GET['month'] ) )
{
    // handle error
}
if ( ! preg_match( "/^[0-9]{1,2}$/", $_GET['day'] ) )
{
    // handle error
}
if ( ! preg_match( "/^[0-9]{4}$/", $_GET['year'] ) )
{
    // handle error
}
Trong ví dụ này, chúng ta có thể kiểm tra đơn giản các số nguyên dương [0-9] với một độ dài 1 hoặc 2 chữ số {1,2}. Nếu dữ liệu không đúng như đầu vào, chúng ta sẽ trả về một thông báo lỗi. Kiểu kiểm tra này ít để lại lỗ hổng cho các tấn công SQL.

PHP có một số công cụ giúp bạn kiểm tra đầu vào. Cơ sở dữ liệu PEAR cũng có một vài package giúp kiểm tra email, ngày tháng và URL.

4. Chú ý tấn công Cross Site Scripting (XSS) trong dữ liệu đầu vào người dùng.

Một ứng dụng web luôn chấp nhận đầu vào từ người dùng và hiển thị chúng. Có rất nhiều mẫu sử dụng bao gồm bình luận, bài viết, bài đăng blog sử dụng HTML. Khi chấp nhận kiểu đầu vào vào HTML rất nguy hiểm bởi nó cho phép JavaScript khởi chạy trong một vài trường hợp không lường trước được. JavaScript được thực thi và cookie có thể bị đánh cắp. Dữ liệu cookie có thể bị giả mạo một tài khoản và cấp quyền truy cập hợp pháp vào dữ liệu trang web.

Có một vài cách bảo vệ chống lại những tấn công như thế này. Một trong số đó là không sử dụng HTML một cách toàn diện. Tuy nhiên đây không phải là cách hay đối với ứng dụng diễn đàn hay blog.

Nếu bạn muốn vô hiệu hóa HTML nhưng vẫn cho phép một vài chuẩn đơn giản. Bạn có thể cho phép những tag HTML như hoặc . Hoặc “BBCode” và “BB Tags”, sử dụng phổ biến trên các diễn đàn là [b]test[/b]. Đây là cách hữu hiệu với các định dạng cùng với việc vô hiệu hóa những thứ nguy hiểm. Bạn có thể cài đặt BBCode với package có sẵn như HTML_BBCodeParser.

bbcode

 

5. Chống lại SQL Injection

Đây là tấn công nổi tiếng nhất trên ứng dụng web. SQL Injection xảy ra khi dữ liệu không được kiểm tra. Nếu những kí tự  này không được lọc bỏ, người dùng có thể sẽ khai thác hệ thống bằng cách tạo ra truy vấn luôn đúng và do đó có thể qua mặt được hệ thống đăng nhập.

May mắn là PHP cung cấp một vài công cụ bảo vệ cơ sở dữ liệu của bạn. Khi bạn kết nối đến máy chủ SQL bạn có thể sử dụng những hàm này với lời gọi đơn giản và biến sẽ luôn an toàn khi truy vấn. hầu hết những cơ sở dữ liệu cùng với PHP đều có hàm bảo vệ.

MySQLi cho phép bạn làm điều đó bằng một trong hai cách. Với hàm mysqli_real_escape_string kết nối đến máy chủ:

$username = mysqli_real_escape_string( $GET['username'] );
mysql_query( "SELECT * FROM tbl_members WHERE username = '".$username."'");

hoặc

$id = $_GET['id'];
$statement = $connection->prepare( "SELECT * FROM tbl_members WHERE id = ?" );
$statement->bind_param( "i", $id );
$statement->execute();

“i” đại diện cho số nguyên nhưng bạn có thể sử dụng “s” dành cho xâu kí tự, “d” dành cho kiểu double và “b” là blob tùy thuộc vào dữ liệu của bạn.

KẾT

Đây là một hướng dẫn nhỏ giúp bảo vệ trang web của bạn. Cuối cùng, để đảm bảo ứng dụng được xây dựng một cách an toàn, hãy tự mình trang bị những kiến thức về web và những lỗ hổng thông thường hay các cuộc tấn công.

Bài viết cùng chủ đề << Cảnh báo lỗ hổng rất nguy hiểm trên các website PHPHàng triệu trang web WordPress và Drupal có nguy cơ bị tê liệt trong vài giây >>

Bình luận

Từ khóa: