1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

fix: the views that take a password or a key keep it out of error reports

No view used sensitive_post_parameters, so once ADMINS is set the error
mail of a failing POST would carry the password or key in plain text.
The user create, edit and password views, the password change, the
compute forms, the host secrets, the VM's root password and its console
settings now mark their POST data sensitive.
This commit is contained in:
catborise 2026-11-05 17:29:51 +03:00
parent d3178154c3
commit 2cbcb8ab2c
6 changed files with 44 additions and 0 deletions

View file

@ -20,6 +20,7 @@ from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.translation import gettext_lazy as _
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_POST
from django.views.decorators.debug import sensitive_post_parameters
from accounts.apps import admin_password_path
from computes.utils import lock_ownership
@ -186,6 +187,7 @@ def account(request, user_id):
)
@sensitive_post_parameters()
@login_required
def change_password(request):
must_change = UserAttributes.objects.filter(

View file

@ -15,6 +15,7 @@ from django.utils import timezone
from django.utils.http import url_has_allowed_host_and_scheme, urlencode
from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import require_POST
from django.views.decorators.debug import sensitive_post_parameters
from instances.models import InstanceTombstone
from instances.report import workbook
from logs.audit import audit, changed_fields, snapshot
@ -124,6 +125,7 @@ def user_list(request):
)
@sensitive_post_parameters()
@superuser_only
def user_create(request):
user_form = forms.UserCreateForm(request.POST or None)
@ -149,6 +151,7 @@ def user_create(request):
)
@sensitive_post_parameters()
@superuser_only
def user_update(request, pk):
user = get_object_or_404(User, pk=pk)
@ -190,6 +193,7 @@ def user_update(request, pk):
)
@sensitive_post_parameters()
@superuser_only
def user_update_password(request, pk):
user = get_object_or_404(User, pk=pk)

View file

@ -8,6 +8,7 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.decorators.debug import sensitive_post_parameters
from instances.models import Instance
from instances.utils import read_list_rows
from libvirt import libvirtError
@ -145,6 +146,7 @@ def instances(request, compute_id):
)
@sensitive_post_parameters()
@superuser_only
def compute_create(request, FormClass):
form = FormClass(request.POST or None)
@ -157,6 +159,7 @@ def compute_create(request, FormClass):
return render(request, "computes/form.html", {"form": form})
@sensitive_post_parameters()
@superuser_only
def compute_update(request, compute_id):
compute = get_object_or_404(Compute, pk=compute_id)

View file

@ -38,6 +38,7 @@ from django.utils import timezone
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy, gettext_noop
from django.views.decorators.http import require_POST
from django.views.decorators.debug import sensitive_post_parameters
from libvirt import (VIR_DOMAIN_PAUSED,
VIR_DOMAIN_RUNNING,
VIR_DOMAIN_SHUTOFF,
@ -1091,6 +1092,7 @@ def access_error(request, err):
return text
@sensitive_post_parameters()
@require_POST
@serialize_instance_mutation
def set_root_pass(request, pk):
@ -2320,6 +2322,7 @@ def clone(request, pk):
return redirect(reverse("instances:instance", args=[pk]))
@sensitive_post_parameters()
@require_POST
@serialize_instance_mutation
def update_console(request, pk):

View file

@ -3,6 +3,7 @@ from computes.models import Compute
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.views.decorators.debug import sensitive_post_parameters
from instances.models import Instance
from libvirt import libvirtError
from logs.audit import audit
@ -11,6 +12,7 @@ from vrtManager.virtsecrets import wvmSecrets
from virtsecrets.forms import USAGE_TEXTS, AddSecret
@sensitive_post_parameters()
@superuser_only
def secrets(request, compute_id):
"""The host's secrets with the VMs and pools that use them; one created,

View file

@ -0,0 +1,30 @@
"""The views that take a password or a key mark their POST data sensitive:
an error report (mail_admins) leaves it out."""
from unittest.mock import patch
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from computes.models import Compute
from instances.models import Instance
class SensitivePostTestCase(TestCase):
def test_each_view_that_takes_a_secret_hides_its_post_data(self):
admin = get_user_model().objects.create_superuser("sens-admin", "s@example.com", "pw")
compute = Compute.objects.create(name="sens-c", hostname="192.0.2.90", login="root", password="", type=1)
vm = Instance.objects.create(compute=compute, name="sens-vm", uuid="aaaaaaaa-0000-0000-0000-000000000091")
self.client.force_login(admin)
self.client.raise_request_exception = False
urls = [reverse("admin:user_create"), reverse("admin:user_update", args=[admin.pk]),
reverse("admin:user_update_password", args=[admin.pk]), reverse("accounts:change_password"),
reverse("add_tcp_host"), reverse("compute_update", args=[compute.pk]),
reverse("virtsecrets", args=[compute.pk]),
reverse("instances:rootpasswd", args=[vm.pk]), reverse("instances:update_console", args=[vm.pk])]
with patch("instances.models.wvmInstance"), patch("virtsecrets.views.wvmSecrets"):
for url in urls:
with self.subTest(url):
response = self.client.post(url, {"password": "S3cret"})
self.assertEqual(response.wsgi_request.sensitive_post_parameters, "__ALL__")