From 0a2a880794121a66dc78bde112244268e8bf959e Mon Sep 17 00:00:00 2001 From: Richard Steinmetz Date: Tue, 2 Jul 2024 16:55:15 +0200 Subject: [PATCH] fix: scan files uploaded to the bulk endpoint Signed-off-by: Richard Steinmetz --- lib/AvirWrapper.php | 106 +++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/lib/AvirWrapper.php b/lib/AvirWrapper.php index 04fe887..faffe3e 100644 --- a/lib/AvirWrapper.php +++ b/lib/AvirWrapper.php @@ -106,46 +106,7 @@ function ($data) use ($scanner) { function () use ($scanner, $path) { $status = $scanner->completeAsyncScan(); if ($status->getNumericStatus() === Status::SCANRESULT_INFECTED) { - //prevent from going to trashbin - if ($this->trashEnabled) { - /** @var ITrashManager $trashManager */ - $trashManager = \OC::$server->query(ITrashManager::class); - $trashManager->pauseTrash(); - } - - $owner = $this->getOwner($path); - $this->unlink($path); - - if ($this->trashEnabled) { - /** @var ITrashManager $trashManager */ - $trashManager = \OC::$server->query(ITrashManager::class); - $trashManager->resumeTrash(); - } - - $this->logger->warning( - 'Infected file deleted. ' . $status->getDetails() - . ' Account: ' . $owner . ' Path: ' . $path, - ['app' => 'files_antivirus'] - ); - - $activity = $this->activityManager->generateEvent(); - $activity->setApp(Application::APP_NAME) - ->setSubject(Provider::SUBJECT_VIRUS_DETECTED_UPLOAD, [$status->getDetails()]) - ->setMessage(Provider::MESSAGE_FILE_DELETED) - ->setObject('', 0, $path) - ->setAffectedUser($owner) - ->setType(Provider::TYPE_VIRUS_DETECTED); - $this->activityManager->publish($activity); - - $this->logger->error('Infected file deleted. ' . $status->getDetails() . - ' File: ' . $path . ' Account: ' . $owner, ['app' => 'files_antivirus']); - - throw new InvalidContentException( - $this->l10n->t( - 'Virus %s is detected in the file. Upload cannot be completed.', - $status->getDetails() - ) - ); + $this->handleInfected($path, $status); } } ); @@ -169,4 +130,69 @@ private function isWritingMode($mode) { ); return in_array($cleanMode, $this->writingModes); } + + /** + * Synchronously scan data that is written to a file by the bulk upload endpoint + * + * @return false|float|int + * @throws InvalidContentException + */ + public function file_put_contents($path, $data) { + if ($this->shouldWrap($path)) { + $scanner = $this->scannerFactory->getScanner($this->mountPoint . $path); + $scanner->initScanner(); + $status = $scanner->scanString($data); + if ($status->getNumericStatus() === Status::SCANRESULT_INFECTED) { + $this->handleInfected($path, $status); + } + } + + return parent::file_put_contents($path, $data); + } + + /** + * @throws InvalidContentException + */ + private function handleInfected(string $path, Status $status): void { + //prevent from going to trashbin + if ($this->trashEnabled) { + /** @var ITrashManager $trashManager */ + $trashManager = \OC::$server->query(ITrashManager::class); + $trashManager->pauseTrash(); + } + + $owner = $this->getOwner($path); + $this->unlink($path); + + if ($this->trashEnabled) { + /** @var ITrashManager $trashManager */ + $trashManager = \OC::$server->query(ITrashManager::class); + $trashManager->resumeTrash(); + } + + $this->logger->warning( + 'Infected file deleted. ' . $status->getDetails() + . ' Account: ' . $owner . ' Path: ' . $path, + ['app' => 'files_antivirus'] + ); + + $activity = $this->activityManager->generateEvent(); + $activity->setApp(Application::APP_NAME) + ->setSubject(Provider::SUBJECT_VIRUS_DETECTED_UPLOAD, [$status->getDetails()]) + ->setMessage(Provider::MESSAGE_FILE_DELETED) + ->setObject('', 0, $path) + ->setAffectedUser($owner) + ->setType(Provider::TYPE_VIRUS_DETECTED); + $this->activityManager->publish($activity); + + $this->logger->error('Infected file deleted. ' . $status->getDetails() . + ' File: ' . $path . ' Account: ' . $owner, ['app' => 'files_antivirus']); + + throw new InvalidContentException( + $this->l10n->t( + 'Virus %s is detected in the file. Upload cannot be completed.', + $status->getDetails() + ) + ); + } }