Thursday, December 31, 2009

ERC Developing

Bất chợt một hôm moi ERC v3 ra xem xét thì nhận thấy rằng ERC có một sơ hở nghiêm trọng làm mất khả năng bảo vệ mà ERC được thiết kế.

session_start();

$limit = 0; // thoi gian (s) han che giua hai lan truy cap
$delay = 3; // thoi gian (s) phai cho de load trang

$last = ($_SESSION['time'] == NULL) ? 0 : $_SESSION['time'];
$_SESSION['time'] = time();

if ( $limit >= (time() - $last) ) {
 //từ chối phục vụ
}
Rõ ràng nếu client không lưu cookies hoặc session thì ERC v3 vô dụng ...

Vậy nên cần chỉnh sửa đôi chút, ngay lần đầu truy cập sẽ kiểm tra session/cookies ngay, nếu không có thì từ đưa link để client click vào tạo session/cookies và dừng phục vụ tại đó chờ có "vé" (session/cookies) mới phục vụ. Tuy nhiên như vầy đã ổn ?

Tất nhiên là tạm ổn, song nó lại giống DNP hay đại loại các script PHP bảo vệ khác, không trong suốt đối với người dùng !!! Đây là cái đích mà J muốn hướng đến !!

Vậy quay trở lại với giải pháp của ERC v2, J cải tiến nó lên bằng cách mỗi client truy cập vào sẽ được set một ERC log riêng với filename là IP của client đó, và ERC sẽ xử lí riêng từng client thay vì hỗn tạp như v2. Kết quả như sau:

- Trong trường hợp bình thường không bị attack nhiều:
$ban = 1;
$clps = 3; // số yêu cầu tối đa cho phép trong một giây

$in = time()."\n";
$log = fopen('erc-'.$_SERVER['REMOTE_ADDR'].'.log', 'a');    fwrite($log, $in);    fclose($log);
$list = file('erc-'.$_SERVER['REMOTE_ADDR'].'.log', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$last = count($list)- 1;

if($last > $clps) {
    if($list[$last - $clps] != $list[$last]) $ban = 0;
} else $ban = 0;

if($ban) {
 echo 'Access Denied, try again in a few seconds';
}

if($last > 15) unlink('erc-'.$_SERVER['REMOTE_ADDR'].'.log');
$ban = 1;


Trong trường hợp bị tấn công nhiều, nên sử dụng .htaccess:
$ban = 1;
$clps = 3; // số yêu cầu tối đa cho phép trong một giây

$in = time()."\n";
$log = fopen('erc-'.$_SERVER['REMOTE_ADDR'].'.log', 'a');    fwrite($log, $in);    fclose($log);
$list = file('erc-'.$_SERVER['REMOTE_ADDR'].'.log', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$last = count($list)- 1;

if($last > $clps) {
    if($list[$last - $clps] != $list[$last]) $ban = 0;
} else $ban = 0;

if($ban) {
    $in = "Deny from ".$_SERVER['REMOTE_ADDR']."\n";
    $lock = fopen('.htaccess','a');
    fwrite($lock, $in);    fclose($lock);
}

if($last > 15) unlink('erc-'.$_SERVER['REMOTE_ADDR'].'.log');
$ban = 1;

1 comment:

  1. code second is error. Because it may be on site, not difrrent site #.

    ReplyDelete