CVE-2022-0514: Insufficient Information (NVD-CWE-noinfo)
value: Business Logic Errors in GitHub repository crater-invoice/crater prior to 6.0.5.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 6.5
Published: 2022-03-21T19:15Z
Repository: https://github.com/crater-invoice/crater
Language: PHP
Files changed: app/Http/Controllers/V1/Admin/Settings/UpdateCompanySettingsController.php, app/Models/Invoice.php, database/migrations/2022_03_04_051438_calculate_base_values_for_invoice_items.php
Commit date: 2022-03-04 12:08:03 +0530
Commit message: Fix tax per item issue & check currency key

Diff: diff --git a/app/Http/Controllers/V1/Admin/Settings/UpdateCompanySettingsController.php b/app/Http/Controllers/V1/Admin/Settings/UpdateCompanySettingsController.php
index 128be75e..84c419a2 100644
--- a/app/Http/Controllers/V1/Admin/Settings/UpdateCompanySettingsController.php
+++ b/app/Http/Controllers/V1/Admin/Settings/UpdateCompanySettingsController.php
@@ -21,15 +21,17 @@ class UpdateCompanySettingsController extends Controller
         $this->authorize('manage company', $company);
 
         $companyCurrency = CompanySetting::getSetting('currency', $request->header('company'));
         $data = $request->settings;
 
-        if ($companyCurrency !== $data['currency'] && $company->hasTransactions()) {
-            return response()->json([
-                'success' => false,
-                'message' => 'Cannot update company currency after transactions are created.'
-            ]);
+        if (array_key_exists('currency', $data)) {
+            if ($companyCurrency !== $data['currency'] && $company->hasTransactions()) {
+                return response()->json([
+                    'success' => false,
+                    'message' => 'Cannot update company currency after transactions are created.'
+                ]);
+            }
         }
 
         CompanySetting::setSettings($data, $request->header('company'));
 
         return response()->json([
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index 464390af..f4da3e67 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -496,10 +496,14 @@ class Invoice extends Model implements HasMedia
             $item = $invoice->items()->create($invoiceItem);
 
             if (array_key_exists('taxes', $invoiceItem) && $invoiceItem['taxes']) {
                 foreach ($invoiceItem['taxes'] as $tax) {
                     $tax['company_id'] = $invoice->company_id;
+                    $tax['exchnage_rate'] = $invoice->exchange_rate;
+                    $tax['base_amount'] = $tax['amount'] * $exchange_rate;
+                    $tax['currency_id'] = $invoice->currency_id;
+
                     if (gettype($tax['amount']) !== "NULL") {
                         if (array_key_exists('recurring_invoice_id', $invoiceItem)) {
                             unset($invoiceItem['recurring_invoice_id']);
                         }
 
diff --git a/database/migrations/2022_03_04_051438_calculate_base_values_for_invoice_items.php b/database/migrations/2022_03_04_051438_calculate_base_values_for_invoice_items.php
new file mode 100644
index 00000000..1c6c877f
--- /dev/null
+++ b/database/migrations/2022_03_04_051438_calculate_base_values_for_invoice_items.php
@@ -0,0 +1,38 @@
+<?php
+
+use Crater\Models\InvoiceItem;
+use Crater\Models\Tax;
+use Illuminate\Database\Migrations\Migration;
+
+class CalculateBaseValuesForInvoiceItems extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        $taxes = Tax::whereRelation('invoiceItem', 'base_amount', null)->get();
+
+        if ($taxes) {
+            $taxes->map(function ($tax) {
+                $invoiceItem = InvoiceItem::find($tax->invoice_item_id);
+                $exchange_rate = $invoiceItem->exchange_rate;
+                $tax->exchange_rate = $exchange_rate;
+                $tax->base_amount = $tax->amount * $exchange_rate;
+                $tax->save();
+            });
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

Vulnerable code:         if ($companyCurrency !== $data['currency'] && $company->hasTransactions()) {
            return response()->json([
                'success' => false,
                'message' => 'Cannot update company currency after transactions are created.'
            ]);
Fixed code:         if (array_key_exists('currency', $data)) {
            if ($companyCurrency !== $data['currency'] && $company->hasTransactions()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot update company currency after transactions are created.'
                ]);
            }
                    $tax['exchnage_rate'] = $invoice->exchange_rate;
                    $tax['base_amount'] = $tax['amount'] * $exchange_rate;
                    $tax['currency_id'] = $invoice->currency_id;

<?php

use Crater\Models\InvoiceItem;
use Crater\Models\Tax;
use Illuminate\Database\Migrations\Migration;

class CalculateBaseValuesForInvoiceItems extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $taxes = Tax::whereRelation('invoiceItem', 'base_amount', null)->get();

        if ($taxes) {
            $taxes->map(function ($tax) {
                $invoiceItem = InvoiceItem::find($tax->invoice_item_id);
                $exchange_rate = $invoiceItem->exchange_rate;
                $tax->exchange_rate = $exchange_rate;
                $tax->base_amount = $tax->amount * $exchange_rate;
                $tax->save();
            });
        }
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}