06/04/2021, 14:46

Một số mẹo bảo mật ckfinder đơn giản - Bảo mật website PHP

Có lẽ ai cũng biết tác dụng của ckfinder là gì rồi nhỉ, đây là một ứng dụng quản lý file được viết ở nhiều ngôn ngữ Server khác nhau. Tuy nhiên trong bài này tôi chỉ đề cập đến ứng dụng ckfinder trong php thôi nhé. Trước khi vào vấn đề chính thì các bạn lưu ý rằng mọi sự thay đổi config cho bộ ...

Có lẽ ai cũng biết tác dụng của ckfinder là gì rồi nhỉ, đây là một ứng dụng quản lý file được viết ở nhiều ngôn ngữ Server khác nhau. Tuy nhiên trong bài này tôi chỉ đề cập đến ứng dụng ckfinder trong php thôi nhé.

Trước khi vào vấn đề chính thì các bạn lưu ý rằng mọi sự thay đổi config cho bộ ckfinder đều được đặt trong file config.php. Cho nên những thay đổi mà tôi code dưới đây đều nằm trong file config.php của ckfinder nhé.

1. Sử dụng hàm CheckAuthentication

Hàm CheckAuthentication là một hàm được sử dụng để cho phép người dùng hiện tại có quyền được sử dụng ckfinder hay là không. Hàm này nếu return false nếu thì sẽ không được phép sử dung, nếu return true thì sẽ được phép sử dụng.

Thông thường để kiểm tra quyền thì ta sẽ dùng Session, tức là bạn sẽ  tạo SESSION  dùng để cho phép sử dụng ckfinder hay là không.

Ví dụ: Tôi sư dụng session với tên là can_use_ckfinder, nếu như tồn tại session can_use_ckfinder và giá trị của can_use_ckfinder = true thì sẽ cho phép, ngược lại không cho phép.

function CheckAuthentication()
{
        // Kiểm tra xem có quyền sử dung hay không
        if (!empty($_SESSION['can_use_ckfinder']) && $_SESSION['can_use_ckfinder']){
            return true;
        }
        return false;
}
Các bạn lưu ý một điều khi sử dụng session trong php thì phải có hàm session_start() ở đầu file nhé.

2. Thêm loại file quản lý

Mặc định khi bạn download ckfinder về nó sẽ tạo cho chúng ta ba loại group file là Images, Files Flash. Tuy nhiên trong thực tế đôi khi bạn muốn tạo thêm một group nào đó nữa thì sao? Rất đơn giản, ckfinder đã hỗ trợ hoàn toàn cho bạn. Đó chính là hệ thống ResourceType, nó nằm trong file config.php và các bạn dễ dàng tìm thấy khi search với từ khóa ResourceType trong chính file đó.

Như tôi nói mặc định đã có 3 loại là Images, Files và Flash được định nghĩa như sau:

$config['ResourceType'][] = Array(
		'name' => 'Files',				// Single quotes not allowed
		'url' => $baseUrl . 'files',
		'directory' => $baseDir . 'files',
		'maxSize' => 0,
		'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip',
		'deniedExtensions' => '');

$config['ResourceType'][] = Array(
		'name' => 'Images',
		'url' => $baseUrl . 'images',
		'directory' => $baseDir . 'images',
		'maxSize' => 0,
		'allowedExtensions' => 'bmp,gif,jpeg,jpg,png',
		'deniedExtensions' => '');

$config['ResourceType'][] = Array(
		'name' => 'Flash',
		'url' => $baseUrl . 'flash',
		'directory' => $baseDir . 'flash',
		'maxSize' => 0,
		'allowedExtensions' => 'swf,flv',
		'deniedExtensions' => '');
Từ đó ta có thể rút ra rằng muốn thêm một group mới thì chỉ cần copy một cái và đổi lại các thông số là được. Và một số điểm lưu ý là tên group (name) phải là duy nhất, allowedExtensions chính là danh sách các đuôi file chấp nhập upload trong group đó.

Bây giờ giả sử hệ thống tôi chỉ sử dụng hình ảnh, như vậy tôi chỉ cần đến group Images nên tôi sẽ xóa đi 2 loại Files và Flash đã có sẵn, chỉ chừa lại mỗi Images như sau:

$config['ResourceType'][] = Array(
		'name' => 'Images',
		'url' => $baseUrl . 'images',
		'directory' => $baseDir . 'images',
		'maxSize' => 0,
		'allowedExtensions' => 'bmp,gif,jpeg,jpg,png',
		'deniedExtensions' => '');
Quá đơn giản nhỉ :D.

2. Sử dụng AccessControl

AccessControl là trình điều khiển phân quyền trong ckfinder, biến này nằm trong file config.php và tên đầy đủ là $AccessControl. Dưới đây là một ví dụ nó tạo mặc định:

$config['AccessControl'][] = Array(
    'role' => '*',
    'resourceType' => '*',  // Tài nguyên (Images | Files | Flash)
    'folder' => '/',        // Folder ảnh hưởng
    'folderView' => true,   // Quyền xem folder
    'folderCreate' => true, // Quyền tạo folder
    'folderRename' => true, // Quyền đổi tên folder
    'folderDelete' => true, // Quyền delete folder
    'fileView' => true,     // Quyền xem file
    'fileUpload' => true,   // Quyền upload file
    'fileRename' => true,   // Quyền đổi tên file
    'fileDelete' => true    // Quyền xóa file
)
Mức độ ảnh hưởng khi phân quyền giữa hàm CheckAuthentication và hệ thống $AccessControl thì hàm CheckAuthentication sẽ cao hơn, nghĩa là hàm CheckAuthentication  sẽ luôn chạy đầu tiên, nếu như hàm này return false thì mặc nhiên hệ thống sẽ hiểu là không có quyền sử dụng và nó ko cần kiểm tra hệ thống $AccessControl nữa.

Ví dụ bây giờ tôi muốn folder system trong thư mục upload/images/system hình chỉ có admin mới dùng được chức năng xóa hình, còn lại thì không được. Như vậy tôi sẽ thêm một rule $AccessControl như sau:

$config['AccessControl'][] = Array(
    'role' => '*',
    'resourceType' => '*',  // Tài nguyên (Images | Files | Flash)
    'folder' => '/',        // Folder ảnh hưởng
    'folderView' => true,   // Quyền xem folder
    'folderCreate' => true, // Quyền tạo folder
    'folderRename' => true, // Quyền đổi tên folder
    'folderDelete' => true, // Quyền delete folder
    'fileView' => true,     // Quyền xem file
    'fileUpload' => true,   // Quyền upload file
    'fileRename' => true,   // Quyền đổi tên file
    'fileDelete' => true    // Quyền xóa file
);

// Nếu không phải là admin
if (!empty($_SESSION['is_admin']) || $_SESSION['is_admin'])
{
    $config['AccessControl'][] = Array(
        'role' => '*',
        'resourceType' => '*',  // Tài nguyên (Images | Files | Flash)
        'folder' => '/system',        // Folder ảnh hưởng
        'folderView' => true,   // Quyền xem folder
        'folderCreate' => true, // Quyền tạo folder
        'folderRename' => true, // Quyền đổi tên folder
        'folderDelete' => false, // Quyền delete folder
        'fileView' => true,     // Quyền xem file
        'fileUpload' => true,   // Quyền upload file
        'fileRename' => true,   // Quyền đổi tên file
        'fileDelete' => false    // Quyền xóa file
    );
}

Các bạn để ý nhé, tôi giữ nguyên AccessControl và thêm một AccessControl mới. Bây giờ bạn có thể custom trong hệ thống của bạn rất dễ dàng rồi đấy. Nếu không làm được thì PM mình sẽ support cho bạn.

3. Remove file ckfinder.html

Đây chính là then chốt của vấn đề. Bạn hãy đổi file ckfinder.html thành ckfinder.php với nội dung tương tự và xử lý kiểm tra quyền, nếu ok thì mới chạy file, ngược lại thì không chạy file đó. Rất nhiều bạn không chú ý file ckfinder.html và hàm CheckAuthentication nên dễ dàng bị hacker tấn công nếu như bị lộ nơi chứa source ckfinder.

Lưu ý: khi thay đổi thành ckfinder.php thì các URL khi kết hợp ckeditor phải chuyển thành ckfinder.php thay vì ckfinder.html nhé

4. Lời kết

Với phân quyền đơn giản trong ckfinder thì tôi chỉ trình bày tới đây, hy vọng một ngày nào đó tôi sẽ ra thêm bài phân quyền nâng cao trong ckfinder.

0