Ngăn chặn CSRF với ZF3
Cross-site request forgery (CSRF) là kiểu tấn công điều hướng người dùng chuyển một thông tin HTTP Request tới một site nào đó. Thông qua tấn công CSRF, mã độc có thể thi hành các lệnh độc hại từ một người dùng mà website tin là hợp lệ, thường thi là các lệnh chuyển thông tin nhạy cảm (shopping card, form thanh toán ...)
Để bảo vệ tấn công CSRF cần thực hiện các việc sau:
- Phải chắc chắn form có phát sinh ngẫu nhiên một mã token và lưu nó ở PHP session
- Thêm vào một phần tử form với thuộc tính ẩn có chứa giá trị token
- Mỗi khi form gửi đến bởi người dùng, tiến hành so sánh giá trị ẩn gửi lên bởi form và giá trị lưu ở PHP Session
Với ZF3 làm việc này rất đơn giản, bạn chỉ cần thêm vào FORM MODEL một phần tử csrf
với cú pháp như sau:
// Add the CSRF field $this->add([ 'type' => 'csrf', 'name' => 'csrf', 'options' => [ 'csrf_options' => [ 'timeout' => 600 ] ], ]);
Ở template Render FORM (.phtml) thì thêm mã dựng phần tử
<?= $this->formElement($form->get('csrf')); ?>
Bảo vệ Form với CAPTCHA
Một CAPTCHA là cách kiểm cha để xác định xem người dùng là NGƯỜI hay ROBOT tự động truy cập site.
Có vài loại CAPTCHA, nó hoạt động theo cách:
- Mỗi chuỗi bí mật (các từ) phát sinh bởi website, lưu tại PHP Session
- Một hình ảnh biến dạng phát sinh dựa trên chuỗi bí mật, ảnh này hiện thị cho người dùng
- Site yêu cầu người dùng nhập các ký tự bằng cách nhìn hình ảnh đã biến dạng đó
- Nếu gõ đúng các từ bí mật, thì đó là người
Zend Framework có sẵn thư viện CAPTCHA, tuy nhiên để sử dụng bạn cần đảm báo đã tích hợp vào dự án bằng lệnh composer
composer require zendframework/zend-captcha
Để sử dụng Captcha kiểu Figlet
chạy thêm lệnh Composer
composer require zendframework/zend-text
Để tích hợp CAPTCHA vào FORM bạn chỉ việc thêm phần tử captcha vào form như sau:
$this->add([ 'type' => 'captcha', 'name' => 'captcha', 'options' => [ 'label' => 'Human check', 'captcha' => [ 'class' => '[captcha_class_name]', //Kiểu captcha va thiết lập tùy loại captcha ], ], ]);
Sau đó ở template (.phtml) thêm đoạn dựng mã HTML cho captcha
<?= $this->formElement($form->get('captcha')); ?>
Giờ bạn mở lại ví dụ ở phần trước (VÍ DỤ VỀ FORM)
và sẽ thực hành thêm mã captcha
vào FORM
Captcha kiểu Figlet
Bạn thêm vào FORM MODEL phần tử captcha như sau:
$form->add([ //$this-> 'type' => 'captcha', 'name' => 'captcha', 'attributes' => [ ], 'options' => [ 'label' => 'Kiểm tra bạn không phải Robot', 'captcha' => [ 'class' => 'Figlet', 'wordLen' => 6, 'expiration' => 600, ], ], ]);
Nhớ là ở template (.phtml) đã thêm mã như trên. Chạy thử sẽ có captcha Figlet
Captcha kiểu Dumb
Bạn thêm vào FORM MODEL phần tử captcha như sau:
$this->add([ //$this-> 'type' => 'captcha', 'name' => 'captcha', 'attributes' => [ ], 'options' => [ 'label' => 'Kiểm tra bạn không phải Robot', 'captcha' => [ 'class' => 'Dumb', 'wordLen' => 2, 'expiration' => 600, 'label'=>'Nhập chuỗi sau theo thứ tự ngược lại:' ], ], ]);
Chạy thử sẽ có captcha Dumb
Captcha kiểu Image
Captcha tạo ra một ảnh các ký tự, sử dụng font chữ do bạn chỉ ra. Bạn thêm vào FORM MODEL phần tử captcha như sau:
$this->add([ //$this-> 'type' => 'captcha', 'name' => 'captcha', 'attributes' => [ ], 'options' => [ 'label' => 'Bạn có phải là người', 'captcha' => [ 'class' => 'Image', 'imgDir' => 'public/img/', //Nơi lưu ảnh captcha 'suffix' => '.png', 'imgUrl' => '/zendform/public/img/', //URL captcha 'imgAlt' => 'CAPTCHA Image', 'font' => 'public/fonts/MidnightBangkok.ttf', //FONT chữ //Lấy font: https://www.1001freefonts.com/ 'fsize' => 60, 'width' => 350, 'height' => 100, 'expiration' => 600, 'dotNoiseLevel' => 40, 'lineNoiseLevel' => 3 ], ], ]);
Chạy thử sẽ có captcha Image
Captcha kiểu ReCaptcha
Là một dịch vụ Captcha của Google, bạn cần tích hợp thêm thư viện bằng lệnh composer sau:
composer require zendframework/zendservice-recaptcha
Bạn vào trang https://www.google.com/recaptcha/ đăng ký và lấy được mã site_key
và secret_key
là mã truy cập API ReCaptcha, sau đó tạo reCaptcha bằng cách
$this->add([ //$this-> 'type' => 'captcha', 'name' => 'captcha', 'attributes' => [ ], 'options' => [ 'captcha' => [ 'class' => 'ReCaptcha', 'site_key' => '.........',//key của bạn điền vào 'secret_key' => '..........'//key của bạn điền vào ], ], ]);