CVE-2023-0438: Cross-Site Request Forgery (CSRF) (CWE-352)
value: Cross-Site Request Forgery (CSRF) in GitHub repository modoboa/modoboa prior to 2.0.4.
CWE description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
CVSS v3 base score: 6.5
Published: 2023-01-23T14:15Z
Repository: https://github.com/modoboa/modoboa
Language: Python
Files changed: modoboa/admin/templates/admin/domain_detail.html, modoboa/admin/views/identity.py
Commit date: 2023-01-23 11:43:13 +0100
Commit message: Force DELETE method for remove permission view.

Avoids CSRF issue.

Diff: diff --git a/modoboa/admin/templates/admin/domain_detail.html b/modoboa/admin/templates/admin/domain_detail.html
index 50f689dcf..45264cf88 100644
--- a/modoboa/admin/templates/admin/domain_detail.html
+++ b/modoboa/admin/templates/admin/domain_detail.html
@@ -123,11 +123,11 @@
             {% if domain.dkim_public_key %}
               <button type="button" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#domain_dkim_key">
                 {% trans "Show key" %}
               </button>
               <button data-toggle="modal" class="btn btn-default btn-xs" data-target="#dkim_regenerate_dialog"><span class="fa fa-refresh"></span></button>
-              
+
               <div class="modal fade" id="dkim_regenerate_dialog" tabindex="-1" role="dialog" aria-labelledby="dkim_regenerate_dialog" aria-hidden="true">
                 <div class="modal-dialog" role="document">
                     <div class="modal-content">
                         <div class="modal-header">
                             <h5 class="modal-title" id="dkim_regenerate_dialog">{% trans "Warning" %}</h5>
@@ -204,10 +204,20 @@
               }
           }).done(function (response) {
               window.location.reload();
           });
       });
+      $('a[name="removeperm"]').click(function (evt) {
+          evt.preventDefault();
+          var $this = $(this);
+          $.ajax({
+              url: $this.attr('href'),
+              method: 'DELETE'
+          }).done(function () {
+              window.location.reload();
+          });
+      });
   });
   function copy(id) {
     navigator.clipboard.writeText(document.getElementById(id).textContent);
   }
   </script>
diff --git a/modoboa/admin/views/identity.py b/modoboa/admin/views/identity.py
index eb6643e2f..8140d93ad 100644
--- a/modoboa/admin/views/identity.py
+++ b/modoboa/admin/views/identity.py
@@ -194,10 +194,11 @@ def delaccount(request, pk):
     )
 
 
 @login_required
 @permission_required("admin.add_domain")
+@require_http_methods(["DELETE"])
 def remove_permission(request):
     domid = request.GET.get("domid", None)
     daid = request.GET.get("daid", None)
     if domid is None or daid is None:
         raise BadRequest(_("Invalid request"))

Fixed code: 
      $('a[name="removeperm"]').click(function (evt) {
          evt.preventDefault();
          var $this = $(this);
          $.ajax({
              url: $this.attr('href'),
              method: 'DELETE'
          }).done(function () {
              window.location.reload();
          });
      });
@require_http_methods(["DELETE"])