はじめに
今回は、baserCMS5にアンチウイルスエンジン「ClamAV」導入し、
アップロード時に自動スキャンする仕組みをプラグインとして組み込んでみました。
※通常のwebサイトにおいてClamAVは不要なことが多いです。
ClamAVとは?
ClamAV は、オープンソースのアンチウイルスエンジンです。
- クロスプラットフォーム対応(Linux / macOS / Windows)
- ウイルス・トロイの木馬・マルウェアなどの検知
- コマンドライン操作が可能
主にメールやWebサーバーでのファイル検査に利用されており、無料なこともあり情報が多く導入しやすいのが特徴です。
baserCMS5のファイルアップロードについて
baserCMS5では、ファイルアップロード機能は、BcUploadビヘイビアを使って実装されていることが多いです。
もちろん、このビヘイビアには、セキュリティ対策が組み込まれていますが
(拡張子チェックやディレクトリトラバーサルなど)
ClamAVを導入してウィルスチェックを行いよりセキュアにしようと考えました。
実装の概要
1. ファイルスキャンサービス
public function scan(string $filePath): int
{
if (!file_exists($filePath)) return Configure::read('ClamavUpload.FILE_IS_UNCHECKED');
$script = Configure::read('ClamavUpload.script');
exec(escapeshellcmd($script) . ' ' . escapeshellarg($filePath) . ' 2>&1', $output, $return_code);
switch ($return_code) {
case 0:
return Configure::read('ClamavUpload.FILE_IS_CLEAN');
case 1:
return Configure::read('ClamavUpload.FILE_IS_INFECTED');
default:
return Configure::read('ClamavUpload.FILE_IS_UNCHECKED');
}
}
2. バリデーションをイベントから追加してチェック
public function BuildValidator(Event $event, Validator $validator, $name)
{
$table = $event->getSubject();
// BcUpload ビヘイビアが設定されていなければ何もしない.
if (!$table->hasBehavior('BcUpload')) return $validator;
$bcUpload = $table->behaviors()->get('BcUpload');
$settings = $bcUpload->getSettings();
$clamavScanner = $this->getService(ClamavScannerInterface::class);
foreach ($settings['fields'] as $field => $fieldSettings) {
// ClamAV によるスキャンバリデーションルールを追加.
$validator->add($field, 'clamavScan', [
'rule' => function ($value, $context) use ($clamavScanner) {
// アップロードされていなければバリデーション対象外.
if (empty($value['uploadable'])) return true;
$filePath = $value['tmp_name'];
$result = $clamavScanner->scan($filePath);
switch ($result) {
case Configure::read('ClamavUpload.FILE_IS_CLEAN'):
return true;
case Configure::read('ClamavUpload.FILE_IS_INFECTED'):
return 'ウイルスが検出されたため、アップロードできません。';
default:
return 'ウイルススキャンに失敗しました。しばらくしてから再度お試しください。';
}
},
'message' => 'アップロードに失敗しました。',
]);
}
return $validator;
}
※モデルのbuildValidatorイベントを定義してBcUploadが設定されているモデルであれば、バリデーションを追加
ClamAV のインストール
動作確認方法(EICARテスト)
ダウンロードしたファイルをアップロードしてテストします。
まとめ
- ClamAV を使えば、オープンソースで高機能なウイルススキャンを CMS に簡単に統合可能
- baserCMS5でもイベントのbuildValidatorを活用すれば自然にスキャンを組み込める
- プラグイン化すれば再利用性も高く、セキュアなファイル管理が実現できる
おわりに
baserCMSが掲げている「コーポレートサイトにちょうど良いサイト」のような用途では、ClamAVを導入する必要はないかもしれません。
しかし、セキュリティ要件が高いようなサイトでもこのように少しプラグイン書くだけ実装できるので、今回はご紹介しました。