Bảo mật cho việc sử dụng PHP Upload Script

Hầu hết các PHP scripts và hệ thống quản lý nội dung (CMS scripts) đề yêu cầu quyền ghi 777 (rwxrwzrwz) phải được set cho các thư mục cho phép upload hình ảnh và tập tin. Nhiều chuyên gia bảo mật cảnh báo rằng việc thiết lập quyền thành 777 đồng nghĩa với việc bất kỳ ai cũng có thể đăng tải bất kỳ nội dung gì lên máy chủ của bạn, cài đặt các mã độc, chạy các chương trình phá hoại và có thể chiếm đoạt quyền quản lý máy chủ. Đây thực sự là một hiểm họa lớn.

Có 2 cách khả dĩ có thể được áp dụng trong trường hợp này:

Cách 1: (thích hợp cho người dùng shared hosting)

1. Gán quyền 775 cho thư mục upload
2. Kiểm tra tập tin bằng cách sử dụng các hàm PHP (nếu upload hình ảnh)
3. Vô hiệu hóa directory indexes và script exection sử dụng .htaccess
4. Đặt thư mục upload ra ngoài thư mục gốc đặt website .

Upload Folder outside WWW Root

Cách đơn giản nhất để bảo vệ nội dung của bạn là di chuyển thư mục ra ngoài tập tin gốc đặt trang web. Nếu là Cpanel thì đó là public_html và trong Plesk là httpdocs. Bằng cách này nội dung của thư mục mà bạn cho phép quyền ghi (writable) sẽ không bị lộ ra bên ngoài.

Trong mã PHP script, bạn thiết lập để có thể truy cập vào thư mục nằm ngoài thư mục web gốc

Code:

./uploads

<img src=”./uploads/photo.gif>

Cho đến lúc này, hacker vẫn có thể đăng tải và chạy các đoạn mã độc trên máy chủ của bạn do vậy bạn cần tạo một tập tin .htaccess vào trong thư mục upload để vô hiệu hóa việc thực thi CGI

Vô hiệu hóa việc thực thi các script và ẩn chỉ mục với .htaccess

Tạo tập tin .htaccess với nội dung như sau

Code:

Options -Indexes
Options -ExecCGI
AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi

Hơn thế nữa, nếu bạn chỉ cho phép người dùng làm việc với các tập tin hình ảnh, bạn có thể cấm các loại tập tin khác bằng cách thêm đoạn code dưới đây vào .htaccess.

Code:

<Files ^(*.jpeg|*.jpg|*.png|*.gif)>
order deny,allow
deny from all
</Files>

Sử dụng các hàm PHP để kiểm tra các tập tin đã được

Điều đầu tiên trong bảo mật tập tin được đăng tải là bạn kiểm tra kích thước và loại file. Do bởi bạn cho phép mọi người có thể upload nên họ có thể up cà VIRUS!

1. Kiểm tra loại tập tin upload và từ chối việc upload các loại file khác.
2. Cấm tập tin dựa trên dung lượng qui định.

Nếu bạn cho phép người dùng đăng tải tập tin hình ảnh (jpg,gif,png) thì mẹo ở đây là sử dụng hàm getimagesize() trong PHP. Nếu tập tin được upload là hình ảnh thì nó sẽ trả lại giá trị là “true” bằng ngược lại sẽ báo lỗi. Hàm getimagesize() còn trả lại thông tin width, height và type của tập tin. Vì vậy đừng quên kiểm tra chiều dài và rộng tập tin hình đã đăng tải nhằm ngăn chặn kích thước chỉ định.

Code:

<?php

// check for uploaded file size

if ($_FILES[‘imagefile’][‘size’] > 50000 )
{
die (“ERROR: Large File Size”);

}

//check if its image file

if (!getimagesize($_FILES[‘imagefile’][‘tmp_name’]))
{ echo “Invalid Image File…”;
exit();
}

// restrict width and height if its image or photo file

list($width, $height, $type, $attr) = getimagesize($_FILES[‘imagefile’][‘tmp_name’]);

if ($width > 100 || $height > 100)
{
echo “Maximum width and height exceeded. Please upload images below 100×100 px size”;
exit();
}

$blacklist = array(“.php”, “.phtml”, “.php3”, “.php4”, “.js”, “.shtml”, “.pl” ,”.py”);
foreach ($blacklist as $file)
{
if(preg_match(“/$file\$/i”, $_FILES[‘userfile’][‘name’]))
{
echo “ERROR: Uploading executable files Not Allowed\n”;
exit;
}
}

?>

Nếu bạn cần từ chối yêu cầu upload từ các tập tin, bạn có thể tạo 1 danh sách blacklist về các tập tin ở dạng array và chạy lặp để kiểm tra phần header. Nhớ rằng đừng tin tưởng vào phần header của trình duyệt vì chúng có thể bị giả mạo.

Ghi chú: Để tham khảo thêm về hàm getimagesize() và kiểm tra danh sách blacklist bạn có thể tải tài liệu này. Link: http://www.scanit.be/uploads/php-file-upload.pdf

Nhớ rằng một khi bạn đã di chuyển thư mục upload ra khỏi thư mục gốc, cách tốt nhất để xuất các tập tin (ở đây giả định là hình ành) thì cách tốt nhất là viết một đoạn mã PHP script (gọi nó là getimage.php), đọc tập tin và gửi phần header ra cho trình duyệt. Xem ví dụ dưới đây.

Code:

// this is just example only

$imgfile = $rsPhoto[‘photo’]; // or value from database

list($width, $height, $type, $attr) = getimagesize($imgfile);

switch ($type)
{

case 1: $im = imagecreatefromgif($imgfile);
header(“Content-type: image/gif”);
break;

case 2:
$im = imagecreatefromjpeg($imgfile);
header(“Content-type: image/jpeg”);
break;

case 3:
$im = imagecreatefrompng($imgfile);
header(“Content-type: image/png”);
break;

}

Cách 2:

Cách tốt nhất là nên quản lý bảo mật cho việc upload tập tin hơn là cho người dùng quyền được phép ghi. Thay vào đó ta sẽ trao quyền ghi cho tài khoản apache. Chỉ việc chuyển quyền sở hữu thư mục cho tài khoản apache hoặc nobody và gán quyền 770 cho thư mục.

Bằng cách này, người ngoài sẽ không thể truy cập vào để đọc / ghi / thực thi trên thư mục upload. Lúc này chỉ có tài khoản apache là có quyền rwx và cũng chính apache là tài khoản sở hữu thư mục upload. Bạn có thể đặt thư mục upload vào trong thư mục web gốc.

Code:

chown -R apache uploads
chmod -R 770 uploads

Nếu có ai đó cố gắng truy cập vào thư mục uploads thông qua địa chỉ URL sẽ xuất hiện thông báo Forbidden.

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: