CVE-2023-3230: Missing Authorization (CWE-862)
value: Missing Authorization in GitHub repository fossbilling/fossbilling prior to 0.5.0.
CWE description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
CVSS v3 base score: 7.5
Published: 2023-06-14T06:15Z
Repository: https://github.com/fossbilling/fossbilling
Language: PHP
Files changed: src/modules/Servicedownloadable/Api/Admin.php, src/modules/Servicedownloadable/Api/Client.php, tests/modules/Servicedownloadable/Api/ClientTest.php
Commit date: 2023-06-12 06:28:36 +0200
Commit message: Fix logical error in Servicedownloadable module (#1311)

* Fix logical error in Servicedownloadable module

* Fix the tests now
Diff: diff --git a/src/modules/Servicedownloadable/Api/Admin.php b/src/modules/Servicedownloadable/Api/Admin.php
index cab04c45..7d9af517 100644
--- a/src/modules/Servicedownloadable/Api/Admin.php
+++ b/src/modules/Servicedownloadable/Api/Admin.php
@@ -27,10 +27,11 @@ class Admin extends \Api_Abstract
     public function upload($data)
     {
         $required = [
             'id' => 'Product ID is missing',
         ];
+
         $this->di['validator']->checkRequiredParamsForArray($required, $data);
 
         $model = $this->di['db']->getExistingModelById('Product', $data['id'], 'Product not found');
 
         if (!isset($_FILES['file_data'])) {
diff --git a/src/modules/Servicedownloadable/Api/Client.php b/src/modules/Servicedownloadable/Api/Client.php
index 155a4b54..589bbf8b 100644
--- a/src/modules/Servicedownloadable/Api/Client.php
+++ b/src/modules/Servicedownloadable/Api/Client.php
@@ -34,11 +34,11 @@ class Client extends \Api_Abstract
             throw new \Box_Exception('Order not found');
         }
 
         $orderService = $this->di['mod_service']('order');
         $s = $orderService->getOrderService($order);
-        if (!$s instanceof \Model_ServiceDownloadable) {
+        if (!$s instanceof \Model_ServiceDownloadable || $order->status !== 'active') {
             throw new \Box_Exception('Order is not activated');
         }
 
         $service = $this->getService();
 
diff --git a/tests/modules/Servicedownloadable/Api/ClientTest.php b/tests/modules/Servicedownloadable/Api/ClientTest.php
index 8773f8ca..5e92d560 100644
--- a/tests/modules/Servicedownloadable/Api/ClientTest.php
+++ b/tests/modules/Servicedownloadable/Api/ClientTest.php
@@ -103,14 +103,18 @@ class ClientTest extends \BBTestCase {
         $orderServiceMock = $this->getMockBuilder('\Box\Mod\Order\Service')->getMock();
         $orderServiceMock->expects($this->atLeastOnce())
             ->method('getOrderService')
             ->will($this->returnValue(new \Model_ServiceDownloadable()));
 
+        $mockOrder = new \Model_ClientOrder();
+        $mockOrder->loadBean(New \DummyBean());
+        $mockOrder->status = "active";
+
         $dbMock = $this->getMockBuilder('\Box_Database')->getMock();
         $dbMock->expects($this->atLeastOnce())
             ->method('findOne')
-            ->will($this->returnValue(new \Model_ClientOrder()));
+            ->will($this->returnValue($mockOrder));
 
         $di = new \Pimple\Container();
         $di['db'] = $dbMock;
         $di['mod_service'] = $di->protect(function() use ($orderServiceMock) {return $orderServiceMock;});
 

Vulnerable code:         if (!$s instanceof \Model_ServiceDownloadable) {
            ->will($this->returnValue(new \Model_ClientOrder()));
Fixed code: 
        if (!$s instanceof \Model_ServiceDownloadable || $order->status !== 'active') {
        $mockOrder = new \Model_ClientOrder();
        $mockOrder->loadBean(New \DummyBean());
        $mockOrder->status = "active";

            ->will($this->returnValue($mockOrder));