CVE-2024-37889: Insufficient Information (NVD-CWE-noinfo)
value: MyFinances is a web application for managing finances. MyFinances has a way to access other customer invoices while signed in as a user. This method allows an actor to access PII and financial information from another account. The vulnerability is fixed in 0.4.6.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-06-14T20:15Z
Repository: https://github.com/TreyWW/MyFinances
Language: Python
Files changed: backend/__init__.py, backend/views/core/invoices/edit.py, pyproject.toml
Commit date: 2024-06-14 17:59:57 +0100
Commit message: Merge pull request from GHSA-4884-3gvp-3wj2

* security fix: added permission check for the view page of editing an invoice

* Version updated from 0.4.5 to 0.4.6

Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com>

---------

Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com>
Diff: diff --git a/backend/__init__.py b/backend/__init__.py
index 98a433b..3dd3d2d 100644
--- a/backend/__init__.py
+++ b/backend/__init__.py
@@ -1 +1 @@
-__version__ = "0.4.5"
+__version__ = "0.4.6"
diff --git a/backend/views/core/invoices/edit.py b/backend/views/core/invoices/edit.py
index 6ba8cab..c4c2096 100644
--- a/backend/views/core/invoices/edit.py
+++ b/backend/views/core/invoices/edit.py
@@ -1,10 +1,11 @@
 from datetime import datetime
 
 from django.contrib import messages
 from django.http import JsonResponse
-from django.shortcuts import render
+from django.http.response import HttpResponse
+from django.shortcuts import render, redirect
 from django.views.decorators.http import require_http_methods
 
 from backend.models import Invoice, Client, InvoiceItem
 from backend.types.htmx import HtmxHttpRequest
 
@@ -54,12 +55,17 @@ def invoice_get_existing_data(invoice_obj):
 
 # gets invoice object from invoice id, convert obj to dict, and renders edit.html while passing the stored invoice values to frontend
 def invoice_edit_page_get(request, invoice_id):
     try:
         invoice = Invoice.objects.get(id=invoice_id)
+
+        if not invoice.has_access(request.user):
+            messages.error(request, "You are not permitted to edit this invoice")
+            return redirect("invoices:dashboard")
     except Invoice.DoesNotExist:
-        return JsonResponse({"message": "Invoice not found"}, status=404)
+        messages.error(request, "Invoice not found")
+        return redirect("invoices:dashboard")
 
     # use to populate fields with existing data in edit_from_destination.html AND edit_to_destination.html
     data_to_populate = invoice_get_existing_data(invoice)
     return render(request, "pages/invoices/edit/edit.html", data_to_populate)
 
@@ -70,16 +76,11 @@ def edit_invoice(request: HtmxHttpRequest, invoice_id):
     try:
         invoice = Invoice.objects.get(id=invoice_id)
     except Invoice.DoesNotExist:
         return JsonResponse({"message": "Invoice not found"}, status=404)
 
-    if request.user.logged_in_as_team and request.user.logged_in_as_team != invoice.organization:
-        return JsonResponse(
-            {"message": "You do not have permission to edit this invoice"},
-            status=403,
-        )
-    elif request.user != invoice.user:
+    if not invoice.has_access(request.user):
         return JsonResponse(
             {"message": "You do not have permission to edit this invoice"},
             status=403,
         )
 
diff --git a/pyproject.toml b/pyproject.toml
index 942dd9a..1593f93 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,8 +1,8 @@
 [tool.poetry]
 name = "MyFinances"
-version = "0.4.5"
+version = "0.4.6"
 description = "github.com/TreyWW/MyFinances"
 authors = ["TreyWW"]
 readme = "README.md"
 
 [tool.poetry.dependencies]
@@ -92,11 +92,11 @@ line-length = 140
 [build-system]
 requires = ["poetry-core"]
 build-backend = "poetry.core.masonry.api"
 
 [tool.bumpversion]
-current_version = "0.4.5"
+current_version = "0.4.6"
 commit = true
 commit_args = "-s"
 tag = true
 tag_name = "v{new_version}"
 sign_tags = true

Vulnerable code: __version__ = "0.4.5"
from django.shortcuts import render
        return JsonResponse({"message": "Invoice not found"}, status=404)
    if request.user.logged_in_as_team and request.user.logged_in_as_team != invoice.organization:
        return JsonResponse(
            {"message": "You do not have permission to edit this invoice"},
            status=403,
        )
    elif request.user != invoice.user:
version = "0.4.5"
current_version = "0.4.5"
Fixed code: __version__ = "0.4.6"
from django.http.response import HttpResponse
from django.shortcuts import render, redirect

        if not invoice.has_access(request.user):
            messages.error(request, "You are not permitted to edit this invoice")
            return redirect("invoices:dashboard")
        messages.error(request, "Invoice not found")
        return redirect("invoices:dashboard")
    if not invoice.has_access(request.user):
version = "0.4.6"
current_version = "0.4.6"