Common Weakness Enumeration

CWE-285

Discouraged

Improper Authorization

Abstraction: Class · Status: Draft

The product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.

2303 vulnerabilities reference this CWE, most recent first.

GHSA-QM33-P5P9-F8VG

Vulnerability from github – Published: 2026-06-08 23:35 – Updated: 2026-06-08 23:35
VLAI
Summary
nebula-mesh: GET /api/v1/audit-log discloses all entries to any operator
Details

internal/api/audit.go:12handleGetAuditLog does no admin check. The route is bearer-auth gated only; any operator API key returns the full audit log via store.ListAuditEntries (up to limit=1000). This includes cross-tenant actor names, host/CA/operator IDs, action timestamps, and masked-IP entries from rate-limit refusals — enough surface for a tenant to enumerate the server's activity, infer staffing patterns, or identify high-value targets.

Affected

All released versions up to v0.3.1.

Reproducer

curl -H "Authorization: Bearer <any-operator-key>" \
  https://server/api/v1/audit-log?limit=1000

Suggested fix

Two options, either acceptable:

  1. if !actorIsAdmin(ctx) { 403 } — strictest; matches the "operator management is admin-only" stance.
  2. Scope to actor: filter store.ListAuditEntries by actor.Username plus a subquery of CA IDs the actor owns. Operators see their own audit entries plus entries against their CA's resources.

Recommend option 1 unless the UI needs per-operator audit views.

Suggested patch

Verified locally: go vet, go test -race -count=1 ./..., golangci-lint v2.12 all clean.

diff --git a/internal/api/audit.go b/internal/api/audit.go
index 3236631..57b57ce 100644
--- a/internal/api/audit.go
+++ b/internal/api/audit.go
@@ -10,6 +10,10 @@ import (
 const defaultAuditLimit = 100

 func (s *Server) handleGetAuditLog(w http.ResponseWriter, r *http.Request) {
+   if !actorIsAdmin(r.Context()) {
+       writeError(w, http.StatusForbidden, "audit log access requires the admin role")
+       return
+   }
    filter := store.AuditFilter{
        Action: r.URL.Query().Get("action"),
        Limit:  defaultAuditLimit,
diff --git a/internal/api/audit_admin_test.go b/internal/api/audit_admin_test.go
new file mode 100644
index 0000000..47e1ca4
--- /dev/null
+++ b/internal/api/audit_admin_test.go
@@ -0,0 +1,62 @@
+package api
+
+import (
+   "context"
+   "crypto/sha256"
+   "encoding/hex"
+   "net/http"
+   "net/http/httptest"
+   "testing"
+
+   "github.com/google/uuid"
+   "github.com/juev/nebula-mesh/internal/models"
+)
+
+// TestHandleGetAuditLog_NonAdminForbidden confirms a non-admin operator
+// API key cannot read the audit log. The legacy config-key path stays
+// admin and is covered by the happy-path test elsewhere.
+func TestHandleGetAuditLog_NonAdminForbidden(t *testing.T) {
+   srv, _ := newTestServer(t)
+
+   nonAdminKey := uuid.New().String()
+   keyHash := sha256.Sum256([]byte(nonAdminKey))
+   if err := srv.store.CreateOperator(context.Background(), &models.Operator{
+       ID: uuid.New().String(), Username: "non-admin", PasswordHash: "x",
+       Role: "user", Status: models.OperatorStatusActive,
+   }); err != nil {
+       t.Fatal(err)
+   }
+   op, err := srv.store.GetOperatorByUsername(context.Background(), "non-admin")
+   if err != nil {
+       t.Fatal(err)
+   }
+   if err := srv.store.CreateOperatorAPIKey(context.Background(), &models.OperatorAPIKey{
+       ID: uuid.New().String(), OperatorID: op.ID, KeyHash: hex.EncodeToString(keyHash[:]),
+   }); err != nil {
+       t.Fatal(err)
+   }
+
+   req := httptest.NewRequest("GET", "/api/v1/audit-log", nil)
+   req.Header.Set("Authorization", "Bearer "+nonAdminKey)
+   rec := httptest.NewRecorder()
+   srv.ServeHTTP(rec, req)
+
+   if rec.Code != http.StatusForbidden {
+       t.Errorf("non-admin audit-log status = %d, want 403", rec.Code)
+   }
+}
+
+// TestHandleGetAuditLog_LegacyKeyAllowed confirms the legacy config-key
+// path still reaches the handler (preserves backward compatibility).
+func TestHandleGetAuditLog_LegacyKeyAllowed(t *testing.T) {
+   srv, _ := newTestServer(t)
+
+   req := httptest.NewRequest("GET", "/api/v1/audit-log", nil)
+   req.Header.Set("Authorization", "Bearer "+testAPIKey)
+   rec := httptest.NewRecorder()
+   srv.ServeHTTP(rec, req)
+
+   if rec.Code == http.StatusForbidden {
+       t.Errorf("legacy key rejected with 403; want pass-through")
+   }
+}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.3.1"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/juev/nebula-mesh"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.3.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-47726"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-08T23:35:55Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "`internal/api/audit.go:12` \u2014 `handleGetAuditLog` does no admin check. The route is bearer-auth gated only; any operator API key returns the full audit log via `store.ListAuditEntries` (up to limit=1000). This includes cross-tenant actor names, host/CA/operator IDs, action timestamps, and masked-IP entries from rate-limit refusals \u2014 enough surface for a tenant to enumerate the server\u0027s activity, infer staffing patterns, or identify high-value targets.\n\n## Affected\nAll released versions up to v0.3.1.\n\n## Reproducer\n```\ncurl -H \"Authorization: Bearer \u003cany-operator-key\u003e\" \\\n  https://server/api/v1/audit-log?limit=1000\n```\n\n## Suggested fix\nTwo options, either acceptable:\n\n1. `if !actorIsAdmin(ctx) { 403 }` \u2014 strictest; matches the \"operator management is admin-only\" stance.\n2. Scope to actor: filter `store.ListAuditEntries` by `actor.Username` plus a subquery of CA IDs the actor owns. Operators see their own audit entries plus entries against their CA\u0027s resources.\n\nRecommend option 1 unless the UI needs per-operator audit views.\n\n## Suggested patch\n\nVerified locally: `go vet`, `go test -race -count=1 ./...`, `golangci-lint v2.12` all clean.\n\n```diff\ndiff --git a/internal/api/audit.go b/internal/api/audit.go\nindex 3236631..57b57ce 100644\n--- a/internal/api/audit.go\n+++ b/internal/api/audit.go\n@@ -10,6 +10,10 @@ import (\n const defaultAuditLimit = 100\n \n func (s *Server) handleGetAuditLog(w http.ResponseWriter, r *http.Request) {\n+\tif !actorIsAdmin(r.Context()) {\n+\t\twriteError(w, http.StatusForbidden, \"audit log access requires the admin role\")\n+\t\treturn\n+\t}\n \tfilter := store.AuditFilter{\n \t\tAction: r.URL.Query().Get(\"action\"),\n \t\tLimit:  defaultAuditLimit,\ndiff --git a/internal/api/audit_admin_test.go b/internal/api/audit_admin_test.go\nnew file mode 100644\nindex 0000000..47e1ca4\n--- /dev/null\n+++ b/internal/api/audit_admin_test.go\n@@ -0,0 +1,62 @@\n+package api\n+\n+import (\n+\t\"context\"\n+\t\"crypto/sha256\"\n+\t\"encoding/hex\"\n+\t\"net/http\"\n+\t\"net/http/httptest\"\n+\t\"testing\"\n+\n+\t\"github.com/google/uuid\"\n+\t\"github.com/juev/nebula-mesh/internal/models\"\n+)\n+\n+// TestHandleGetAuditLog_NonAdminForbidden confirms a non-admin operator\n+// API key cannot read the audit log. The legacy config-key path stays\n+// admin and is covered by the happy-path test elsewhere.\n+func TestHandleGetAuditLog_NonAdminForbidden(t *testing.T) {\n+\tsrv, _ := newTestServer(t)\n+\n+\tnonAdminKey := uuid.New().String()\n+\tkeyHash := sha256.Sum256([]byte(nonAdminKey))\n+\tif err := srv.store.CreateOperator(context.Background(), \u0026models.Operator{\n+\t\tID: uuid.New().String(), Username: \"non-admin\", PasswordHash: \"x\",\n+\t\tRole: \"user\", Status: models.OperatorStatusActive,\n+\t}); err != nil {\n+\t\tt.Fatal(err)\n+\t}\n+\top, err := srv.store.GetOperatorByUsername(context.Background(), \"non-admin\")\n+\tif err != nil {\n+\t\tt.Fatal(err)\n+\t}\n+\tif err := srv.store.CreateOperatorAPIKey(context.Background(), \u0026models.OperatorAPIKey{\n+\t\tID: uuid.New().String(), OperatorID: op.ID, KeyHash: hex.EncodeToString(keyHash[:]),\n+\t}); err != nil {\n+\t\tt.Fatal(err)\n+\t}\n+\n+\treq := httptest.NewRequest(\"GET\", \"/api/v1/audit-log\", nil)\n+\treq.Header.Set(\"Authorization\", \"Bearer \"+nonAdminKey)\n+\trec := httptest.NewRecorder()\n+\tsrv.ServeHTTP(rec, req)\n+\n+\tif rec.Code != http.StatusForbidden {\n+\t\tt.Errorf(\"non-admin audit-log status = %d, want 403\", rec.Code)\n+\t}\n+}\n+\n+// TestHandleGetAuditLog_LegacyKeyAllowed confirms the legacy config-key\n+// path still reaches the handler (preserves backward compatibility).\n+func TestHandleGetAuditLog_LegacyKeyAllowed(t *testing.T) {\n+\tsrv, _ := newTestServer(t)\n+\n+\treq := httptest.NewRequest(\"GET\", \"/api/v1/audit-log\", nil)\n+\treq.Header.Set(\"Authorization\", \"Bearer \"+testAPIKey)\n+\trec := httptest.NewRecorder()\n+\tsrv.ServeHTTP(rec, req)\n+\n+\tif rec.Code == http.StatusForbidden {\n+\t\tt.Errorf(\"legacy key rejected with 403; want pass-through\")\n+\t}\n+}\n```",
  "id": "GHSA-qm33-p5p9-f8vg",
  "modified": "2026-06-08T23:35:55Z",
  "published": "2026-06-08T23:35:55Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/juev/nebula-mesh/security/advisories/GHSA-qm33-p5p9-f8vg"
    },
    {
      "type": "WEB",
      "url": "https://github.com/forgekeep/nebula-mesh/commit/8baaace54c2a23e7c351b3efab5a31ab07b125dc"
    },
    {
      "type": "WEB",
      "url": "https://github.com/forgekeep/nebula-mesh/releases/tag/v0.3.2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/juev/nebula-mesh"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "nebula-mesh: GET /api/v1/audit-log discloses all entries to any operator"
}

GHSA-QM77-MQF3-FMHQ

Vulnerability from github – Published: 2024-08-14 12:35 – Updated: 2025-10-23 22:22
VLAI
Summary
Magento Improper Authorization leads to security feature bypass
Details

Magento versions 2.4.7-p1, 2.4.6-p6, 2.4.5-p8, 2.4.4-p9 and earlier are affected by an Improper Authorization vulnerability that could result in a Security feature bypass. A low-privileged attacker could leverage this vulnerability to bypass security measures and disclose minor information. Exploitation of this issue does not require user interaction.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/project-community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "2.0.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.7-beta1"
            },
            {
              "fixed": "2.4.7-p2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.6-p1"
            },
            {
              "fixed": "2.4.6-p7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.5-p1"
            },
            {
              "fixed": "2.4.5-p9"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.4.4-p10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.4"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.5"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.6"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.7"
      ]
    }
  ],
  "aliases": [
    "CVE-2024-39411"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-10-23T22:22:41Z",
    "nvd_published_at": "2024-08-14T12:15:27Z",
    "severity": "MODERATE"
  },
  "details": "Magento versions 2.4.7-p1, 2.4.6-p6, 2.4.5-p8, 2.4.4-p9 and earlier are affected by an Improper Authorization vulnerability that could result in a Security feature bypass. A low-privileged attacker could leverage this vulnerability to bypass security measures and disclose minor information. Exploitation of this issue does not require user interaction.",
  "id": "GHSA-qm77-mqf3-fmhq",
  "modified": "2025-10-23T22:22:41Z",
  "published": "2024-08-14T12:35:02Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-39411"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/magento/magento2"
    },
    {
      "type": "WEB",
      "url": "https://helpx.adobe.com/security/products/magento/apsb24-61.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Magento Improper Authorization leads to security feature bypass"
}

GHSA-QM84-V26J-7PCH

Vulnerability from github – Published: 2024-08-15 15:30 – Updated: 2024-08-16 15:31
VLAI
Details
  • Unprotected privileged mode access through UDS session in the Blind Spot Detection Sensor ECU firmware in Nissan Altima (2022) allows attackers to trigger denial-of-service (DoS) by unauthorized access to the ECU's programming session.
  • No preconditions implemented for ECU management functionality through UDS session in the Blind Spot Detection Sensor ECU in Nissan Altima (2022) allows attackers to disrupt normal ECU operations by triggering a control command without authentication.
Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-6347"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-08-15T15:15:22Z",
    "severity": "MODERATE"
  },
  "details": "*  Unprotected privileged mode access through UDS session in the Blind Spot Detection Sensor ECU firmware in Nissan Altima (2022) allows attackers to trigger denial-of-service (DoS) by unauthorized access to the ECU\u0027s programming session.\n  *  No preconditions implemented for ECU management functionality through UDS session in the Blind Spot Detection Sensor ECU in Nissan Altima (2022) allows attackers to disrupt normal ECU operations by triggering a control command without authentication.",
  "id": "GHSA-qm84-v26j-7pch",
  "modified": "2024-08-16T15:31:40Z",
  "published": "2024-08-15T15:30:58Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-6347"
    },
    {
      "type": "WEB",
      "url": "https://asrg.io/security-advisories/CVE-2024-6347"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:L/SC:L/SI:L/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:Y/R:X/V:D/RE:H/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-QP77-FF7G-3Q58

Vulnerability from github – Published: 2023-01-06 12:31 – Updated: 2023-01-12 18:30
VLAI
Details

A vulnerability was found in Forged Alliance Forever up to 3746. It has been declared as critical. Affected by this vulnerability is an unknown functionality of the component Vote Handler. The manipulation leads to improper authorization. Upgrading to version 3747 is able to address this issue. The name of the patch is 6880971bd3d73d942384aff62d53058c206ce644. It is recommended to upgrade the affected component. The associated identifier of this vulnerability is VDB-217555.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-4879"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-01-06T11:15:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability was found in Forged Alliance Forever up to 3746. It has been declared as critical. Affected by this vulnerability is an unknown functionality of the component Vote Handler. The manipulation leads to improper authorization. Upgrading to version 3747 is able to address this issue. The name of the patch is 6880971bd3d73d942384aff62d53058c206ce644. It is recommended to upgrade the affected component. The associated identifier of this vulnerability is VDB-217555.",
  "id": "GHSA-qp77-ff7g-3q58",
  "modified": "2023-01-12T18:30:29Z",
  "published": "2023-01-06T12:31:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-4879"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FAForever/fa/pull/4398"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FAForever/fa/commit/6880971bd3d73d942384aff62d53058c206ce644"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FAForever/fa/releases/tag/3747"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.217555"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.217555"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-QPJH-642G-HGH8

Vulnerability from github – Published: 2022-05-14 02:00 – Updated: 2025-04-12 13:03
VLAI
Details

curl and libcurl before 7.50.1 do not check the client certificate when choosing the TLS connection to reuse, which might allow remote attackers to hijack the authentication of the connection by leveraging a previously created connection with a different client certificate.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2016-5420"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2016-08-10T14:59:00Z",
    "severity": "HIGH"
  },
  "details": "curl and libcurl before 7.50.1 do not check the client certificate when choosing the TLS connection to reuse, which might allow remote attackers to hijack the authentication of the connection by leveraging a previously created connection with a different client certificate.",
  "id": "GHSA-qpjh-642g-hgh8",
  "modified": "2025-04-12T13:03:30Z",
  "published": "2022-05-14T02:00:03Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-5420"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2018:3558"
    },
    {
      "type": "WEB",
      "url": "https://curl.haxx.se/docs/adv_20160803B.html"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/GLPXQQKURBQFM4XM6645VRPTOE2AWG33"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/K3GQH4V3XAQ5Z53AMQRDEC3C3UHTW7QR"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GLPXQQKURBQFM4XM6645VRPTOE2AWG33"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/K3GQH4V3XAQ5Z53AMQRDEC3C3UHTW7QR"
    },
    {
      "type": "WEB",
      "url": "https://security.gentoo.org/glsa/201701-47"
    },
    {
      "type": "WEB",
      "url": "https://source.android.com/security/bulletin/2016-12-01.html"
    },
    {
      "type": "WEB",
      "url": "https://www.tenable.com/security/tns-2016-18"
    },
    {
      "type": "WEB",
      "url": "http://lists.opensuse.org/opensuse-updates/2016-09/msg00011.html"
    },
    {
      "type": "WEB",
      "url": "http://lists.opensuse.org/opensuse-updates/2016-09/msg00094.html"
    },
    {
      "type": "WEB",
      "url": "http://rhn.redhat.com/errata/RHSA-2016-2575.html"
    },
    {
      "type": "WEB",
      "url": "http://rhn.redhat.com/errata/RHSA-2016-2957.html"
    },
    {
      "type": "WEB",
      "url": "http://www.debian.org/security/2016/dsa-3638"
    },
    {
      "type": "WEB",
      "url": "http://www.oracle.com/technetwork/security-advisory/cpuoct2018-4428296.html"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/92309"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id/1036537"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id/1036739"
    },
    {
      "type": "WEB",
      "url": "http://www.slackware.com/security/viewer.php?l=slackware-security\u0026y=2016\u0026m=slackware-security.563059"
    },
    {
      "type": "WEB",
      "url": "http://www.ubuntu.com/usn/USN-3048-1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-QPM9-H556-MWXM

Vulnerability from github – Published: 2026-07-08 21:11 – Updated: 2026-07-08 21:11
VLAI
Summary
NL Portal: Missing per-user authorization on document and decision GraphQL queries in nl-portal-backend-libraries
Details

Impact

In versions up to and including 3.0.0, two parts of the GraphQL API returned data without checking whether the data belonged to the logged-in user:

  • Document content. A logged-in user could download the raw content of any document by its ID, regardless of who owned it. The resolver has lacked an authentication parameter since the initial commit of the project (2022-11-22) — so every version of nl.nl-portal:documenten-api ever published is affected (the earliest one on Maven Central is 0.2.2.RELEASE, published 2023-08-31).
  • Decisions (besluiten). A logged-in user could list, search, and read decision records — including their audit trails and the documents attached to them — for any user. The list query also accepted filters (decision type, identification, responsible organisation, related case), which made it easy to enumerate decisions across the user base. The besluiten module was introduced in the 1.5.x release line (commit 9229460b, 2024-08-19), so versions of nl.nl-portal:besluiten from 1.5.0 through 3.0.0 are affected.

Decisions and their attachments often contain sensitive personal data (decisions on benefits, permits, objections, and similar), so the confidentiality impact is high. The two endpoints also chain naturally: once an attacker has discovered another user's document IDs by enumerating decisions, they can pull those documents' contents through the document endpoint.

Why these two findings are reported together

They share the same root cause and the same shape. Both GraphQL resolvers were declared without an authentication parameter on the method signature, which meant the framework never bound the authenticated user into the resolver and the resolver therefore could not perform per-user authorization checks. The fix pattern is the same — bind the authenticated principal into the resolver, or remove the resolver entirely. And in practice the two endpoints reinforce each other as a chain (enumerate via decisions, exfiltrate via documents), so they describe a single end-to-end weakness in the GraphQL surface.

Patches

Upgrade to 3.0.1 or later.

  • nl.nl-portal:documenten-api — the resolver now declares the authentication parameter, so the framework binds the authenticated user into the call path. Fix commit: 32e0ebdf — "Add auth on DocumentContentQuery.kt".
  • nl.nl-portal:besluiten — the entire besluiten module is removed in 3.0.1. Consumers who rely on the besluiten functionality must implement a replacement at the application layer with explicit per-user authorization on every resolver before upgrading. Fix commit: f592af1b — "Removal of Besluiten API".

Workarounds

For deployments that cannot upgrade immediately:

  • Block the following GraphQL operations at the API gateway: getDocumentContent, getBesluiten, getBesluit, getBesluitAuditTrails, getBesluitAuditTrail, getBesluitDocumenten, getBesluitDocument.
  • If per-operation blocking is not possible, block the besluiten module's GraphQL types entirely and block the document-content query.

Technical details

  • nl.nlportal.documentenapi.graphql.DocumentContentQuery.getDocumentContent(documentApi, id) did not declare a CommonGroundAuthentication parameter on the resolver. The authenticated principal was therefore not bound into the call path and document content could be retrieved without the resolver participating in user-scoped authorization. Patched by adding authentication: CommonGroundAuthentication to the resolver signature, so Spring's argument resolution rejects unauthenticated invocations of the query.
  • nl.nlportal.besluiten.graphql.BesluitenQuery exposed six GraphQL operations — getBesluiten, getBesluit, getBesluitAuditTrails, getBesluitAuditTrail, getBesluitDocumenten, getBesluitDocument — none of which declared a CommonGroundAuthentication parameter. In particular, getBesluiten accepted filter arguments (besluitType, identificatie, verantwoordelijkeOrganisatie, zaak, pageNumber) but performed no user scoping, allowing callers to enumerate besluit records across users. The point-lookup operations (getBesluit, getBesluitAuditTrail, getBesluitDocument) returned data for any UUID without ownership checks. The fix is the removal of BesluitenQuery, BesluitenAutoConfiguration, and the integration test, and the autoconfiguration entry has been unwired from the application defaults.

Credits

Discovered during the nl-portal-backend-libraries penetration testing engagement (phase 1, May 2026). Vendor attribution to be added before publication.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.0.0"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "nl.nl-portal:documenten-api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.0.0"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "nl.nl-portal:besluiten"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.5.0"
            },
            {
              "fixed": "3.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-49463"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-200",
      "CWE-285"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-08T21:11:54Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Impact\n\nIn versions up to and including 3.0.0, two parts of the GraphQL API returned data without checking whether the data belonged to the logged-in user:\n\n- **Document content.** A logged-in user could download the raw content of any document by its ID, regardless of who owned it. The resolver has lacked an authentication parameter since the initial commit of the project (2022-11-22) \u2014 so every version of `nl.nl-portal:documenten-api` ever published is affected (the earliest one on Maven Central is `0.2.2.RELEASE`, published 2023-08-31).\n- **Decisions (`besluiten`).** A logged-in user could list, search, and read decision records \u2014 including their audit trails and the documents attached to them \u2014 for any user. The list query also accepted filters (decision type, identification, responsible organisation, related case), which made it easy to enumerate decisions across the user base. The `besluiten` module was introduced in the `1.5.x` release line (commit `9229460b`, 2024-08-19), so versions of `nl.nl-portal:besluiten` from `1.5.0` through `3.0.0` are affected.\n\nDecisions and their attachments often contain sensitive personal data (decisions on benefits, permits, objections, and similar), so the confidentiality impact is high. The two endpoints also chain naturally: once an attacker has discovered another user\u0027s document IDs by enumerating decisions, they can pull those documents\u0027 contents through the document endpoint.\n\n### Why these two findings are reported together\n\nThey share the same root cause and the same shape. Both GraphQL resolvers were declared without an authentication parameter on the method signature, which meant the framework never bound the authenticated user into the resolver and the resolver therefore could not perform per-user authorization checks. The fix pattern is the same \u2014 bind the authenticated principal into the resolver, or remove the resolver entirely. And in practice the two endpoints reinforce each other as a chain (enumerate via decisions, exfiltrate via documents), so they describe a single end-to-end weakness in the GraphQL surface.\n\n## Patches\n\nUpgrade to **3.0.1** or later.\n\n- **`nl.nl-portal:documenten-api`** \u2014 the resolver now declares the authentication parameter, so the framework binds the authenticated user into the call path. Fix commit: `32e0ebdf` \u2014 \"Add auth on DocumentContentQuery.kt\".\n- **`nl.nl-portal:besluiten`** \u2014 the entire `besluiten` module is removed in 3.0.1. Consumers who rely on the besluiten functionality must implement a replacement at the application layer with explicit per-user authorization on every resolver before upgrading. Fix commit: `f592af1b` \u2014 \"Removal of Besluiten API\".\n\n## Workarounds\n\nFor deployments that cannot upgrade immediately:\n\n- Block the following GraphQL operations at the API gateway: `getDocumentContent`, `getBesluiten`, `getBesluit`, `getBesluitAuditTrails`, `getBesluitAuditTrail`, `getBesluitDocumenten`, `getBesluitDocument`.\n- If per-operation blocking is not possible, block the `besluiten` module\u0027s GraphQL types entirely and block the document-content query.\n\n## Technical details\n\n- `nl.nlportal.documentenapi.graphql.DocumentContentQuery.getDocumentContent(documentApi, id)` did not declare a `CommonGroundAuthentication` parameter on the resolver. The authenticated principal was therefore not bound into the call path and document content could be retrieved without the resolver participating in user-scoped authorization. Patched by adding `authentication: CommonGroundAuthentication` to the resolver signature, so Spring\u0027s argument resolution rejects unauthenticated invocations of the query.\n- `nl.nlportal.besluiten.graphql.BesluitenQuery` exposed six GraphQL operations \u2014 `getBesluiten`, `getBesluit`, `getBesluitAuditTrails`, `getBesluitAuditTrail`, `getBesluitDocumenten`, `getBesluitDocument` \u2014 none of which declared a `CommonGroundAuthentication` parameter. In particular, `getBesluiten` accepted filter arguments (`besluitType`, `identificatie`, `verantwoordelijkeOrganisatie`, `zaak`, `pageNumber`) but performed no user scoping, allowing callers to enumerate besluit records across users. The point-lookup operations (`getBesluit`, `getBesluitAuditTrail`, `getBesluitDocument`) returned data for any UUID without ownership checks. The fix is the removal of `BesluitenQuery`, `BesluitenAutoConfiguration`, and the integration test, and the autoconfiguration entry has been unwired from the application defaults.\n\n## Credits\n\nDiscovered during the nl-portal-backend-libraries penetration testing engagement (phase 1, May 2026). Vendor attribution to be added before publication.",
  "id": "GHSA-qpm9-h556-mwxm",
  "modified": "2026-07-08T21:11:54Z",
  "published": "2026-07-08T21:11:54Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nl-portal/nl-portal-backend-libraries/security/advisories/GHSA-qpm9-h556-mwxm"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nl-portal/nl-portal-backend-libraries"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "NL Portal: Missing per-user authorization on document and decision GraphQL queries in nl-portal-backend-libraries"
}

GHSA-QPP7-742Q-58J3

Vulnerability from github – Published: 2024-10-10 12:31 – Updated: 2024-10-11 18:27
VLAI
Summary
Magento Open Source Improper Authorization vulnerability
Details

Magento Open Source versions 2.4.7-p2, 2.4.6-p7, 2.4.5-p9, 2.4.4-p10 and earlier are affected by an Improper Authorization vulnerability that could result in a Security feature bypass. A low-privileged attacker could leverage this vulnerability to bypass security measures and have a low impact on integrity and availability. Exploitation of this issue does not require user interaction.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.7-beta1"
            },
            {
              "fixed": "2.4.7-p3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.6-p1"
            },
            {
              "fixed": "2.4.6-p8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.4.5-p1"
            },
            {
              "fixed": "2.4.5-p10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.4.4-p11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.7"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.6"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.5"
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "magento/community-edition"
      },
      "versions": [
        "2.4.4"
      ]
    }
  ],
  "aliases": [
    "CVE-2024-45128"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-11T18:27:17Z",
    "nvd_published_at": "2024-10-10T10:15:06Z",
    "severity": "MODERATE"
  },
  "details": "Magento Open Source versions 2.4.7-p2, 2.4.6-p7, 2.4.5-p9, 2.4.4-p10 and earlier are affected by an Improper Authorization vulnerability that could result in a Security feature bypass. A low-privileged attacker could leverage this vulnerability to bypass security measures and have a low impact on integrity and availability. Exploitation of this issue does not require user interaction.",
  "id": "GHSA-qpp7-742q-58j3",
  "modified": "2024-10-11T18:27:17Z",
  "published": "2024-10-10T12:31:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-45128"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/magento/magento2"
    },
    {
      "type": "WEB",
      "url": "https://helpx.adobe.com/security/products/magento/apsb24-73.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Magento Open Source Improper Authorization vulnerability"
}

GHSA-QPV7-HGM5-VR7R

Vulnerability from github – Published: 2025-10-25 06:30 – Updated: 2025-10-25 06:30
VLAI
Details

The Password Protected plugin for WordPress is vulnerable to authorization bypass via IP address spoofing in all versions up to, and including, 2.7.11. This is due to the plugin trusting client-controlled HTTP headers (such as X-Forwarded-For, HTTP_CLIENT_IP, and similar headers) to determine user IP addresses in the pp_get_ip_address() function when the "Use transients" feature is enabled. This makes it possible for attackers to bypass authorization by spoofing these headers with the IP address of a legitimately authenticated user, granted the "Use transients" option is enabled (non-default configuration) and the site is not behind a CDN or reverse proxy that overwrites these headers.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-11244"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-10-25T06:15:34Z",
    "severity": "LOW"
  },
  "details": "The Password Protected plugin for WordPress is vulnerable to authorization bypass via IP address spoofing in all versions up to, and including, 2.7.11. This is due to the plugin trusting client-controlled HTTP headers (such as X-Forwarded-For, HTTP_CLIENT_IP, and similar headers) to determine user IP addresses in the `pp_get_ip_address()` function when the \"Use transients\" feature is enabled. This makes it possible for attackers to bypass authorization by spoofing these headers with the IP address of a legitimately authenticated user, granted the \"Use transients\" option is enabled (non-default configuration) and the site is not behind a CDN or reverse proxy that overwrites these headers.",
  "id": "GHSA-qpv7-hgm5-vr7r",
  "modified": "2025-10-25T06:30:15Z",
  "published": "2025-10-25T06:30:15Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-11244"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/password-protected/tags/2.7.11/includes/transient-functions.php#L33"
    },
    {
      "type": "WEB",
      "url": "https://research.cleantalk.org/cve-2025-11244"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/30b4371d-54a2-4111-ad2c-b38b6b31884d?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-QPW8-MJ26-5RC9

Vulnerability from github – Published: 2023-11-14 21:31 – Updated: 2023-11-14 21:31
VLAI
Details

Improper authorization in some Intel Battery Life Diagnostic Tool installation software before version 2.2.1 may allow a privilaged user to potentially enable escalation of privilege via local access.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-32662"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-11-14T19:15:26Z",
    "severity": "MODERATE"
  },
  "details": "Improper authorization in some Intel Battery Life Diagnostic Tool installation software before version 2.2.1 may allow a privilaged user to potentially enable escalation of privilege via local access.",
  "id": "GHSA-qpw8-mj26-5rc9",
  "modified": "2023-11-14T21:31:02Z",
  "published": "2023-11-14T21:31:02Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32662"
    },
    {
      "type": "WEB",
      "url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00843.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-QQ2C-2Q8J-JH27

Vulnerability from github – Published: 2026-07-02 18:45 – Updated: 2026-07-02 18:45
VLAI
Summary
Craft CMS: Authorship spoofing in `entries/save-entry` via pre-check/post-mutation authorization gap
Details

Summary

EntriesController::actionSaveEntry() performs entry-edit permission checks before request-controlled author changes are applied to the model. The subsequent author mutation path accepts attacker-supplied authors / author parameters and allows the change when the current user is one of the old authors. Because the controller does not re-run authorization after mutating the author list, a low-privileged user can reassign an entry’s authorship to another user without holding the dedicated peer-author-change permission.

Details

The control flow begins in EntriesController.php:249. actionSaveEntry() loads the entry and enforces edit permissions before calling _populateEntryModel():

public function actionSaveEntry(bool $duplicate = false): ?Response
{
    ...
    $entry = $this->_editableEntry($this->request->getBodyParam('entryId'), $siteId);
    ...
    $this->enforceEditEntryPermissions($entry, $duplicate);
    ...
    $this->_populateEntryModel($entry);
    ...
    $success = Craft::$app->getElements()->saveElement($entry);
}

The attacker-controlled source is in EntriesController.php:588:

$entry->setAttributesFromRequest(array_filter([
    'authorIds' => $this->request->getBodyParam('authors') ??
        $this->request->getBodyParam('author') ??
        $entry->getAuthorId() ??
        static::currentUser()->id,
]));

Entry::setAttributesFromRequest() in Entry.php:1124 extracts the new author IDs and applies them if canChangeAuthor() returns true:

if (
    ($authorIds !== null || $authorId !== null) &&
    $this->canChangeAuthor()
) {
    $this->_oldAuthorIds = $oldAuthorIds;
    $this->setAuthorIds($authorIds);
}

canChangeAuthor() at Entry.php:2789 allows the author change when the current user can view peer entries and is already one of the existing authors:

return (
    empty($authorIds) ||
    in_array($user->id, $authorIds) ||
    $user->can("changeAuthorForPeerEntries:$section->uid")
);

After the author list is mutated, the controller does not re-check authorization.

This closes the exploit chain:

  1. External source: authenticated request to entries/save-entry with attacker-controlled authors[].
  2. Trust boundary failure: authorization is checked on the pre-mutation entry state, not on the post-mutation author assignment.
  3. Privileged sink: the author relationship is rewritten in persistent storage.

Preconditions derived from the source:

  1. The attacker is authenticated and can edit entry 345.
  2. The attacker is among the existing authors of entry 345, or otherwise satisfies canChangeAuthor() through the old author set.
  3. The attacker has viewPeerEntries for the section.
  4. User ID 1 exists and can be assigned as an author in that section.

Result:

  1. enforceEditEntryPermissions() succeeds on the original entry state.
  2. _populateEntryModel() reads authors[]=1 from the request body.
  3. setAttributesFromRequest() updates authorIds because canChangeAuthor() is evaluated against the old authorship state.
  4. saveElement() persists the change and _saveAuthors() rewrites the entry-author relation.
  5. Entry 345 now appears authored by user 1.

Impact

This allows low-privileged users to falsify content ownership and alter the authorship of entries without having the dedicated author-management permission. The impact includes corrupted audit trails, misleading notifications, broken approval workflows, and unauthorized reassignment of content responsibility.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "craftcms/cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.0.0-RC1"
            },
            {
              "fixed": "5.9.21"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-50279"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-02T18:45:28Z",
    "nvd_published_at": "2026-07-02T00:16:44Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\n`EntriesController::actionSaveEntry()` performs entry-edit permission checks before request-controlled author changes are applied to the model. The subsequent author mutation path accepts attacker-supplied `authors` / `author` parameters and allows the change when the current user is one of the old authors. Because the controller does not re-run authorization after mutating the author list, a low-privileged user can reassign an entry\u2019s authorship to another user without holding the dedicated peer-author-change permission.\n\n### Details\nThe control flow begins in [EntriesController.php](/D:/files/projects/cms-5.9.19/cms-5.9.19/src/controllers/EntriesController.php):249. `actionSaveEntry()` loads the entry and enforces edit permissions before calling `_populateEntryModel()`:\n\n```php\npublic function actionSaveEntry(bool $duplicate = false): ?Response\n{\n    ...\n    $entry = $this-\u003e_editableEntry($this-\u003erequest-\u003egetBodyParam(\u0027entryId\u0027), $siteId);\n    ...\n    $this-\u003eenforceEditEntryPermissions($entry, $duplicate);\n    ...\n    $this-\u003e_populateEntryModel($entry);\n    ...\n    $success = Craft::$app-\u003egetElements()-\u003esaveElement($entry);\n}\n```\n\nThe attacker-controlled source is in [EntriesController.php](/D:/files/projects/cms-5.9.19/cms-5.9.19/src/controllers/EntriesController.php):588:\n\n```php\n$entry-\u003esetAttributesFromRequest(array_filter([\n    \u0027authorIds\u0027 =\u003e $this-\u003erequest-\u003egetBodyParam(\u0027authors\u0027) ??\n        $this-\u003erequest-\u003egetBodyParam(\u0027author\u0027) ??\n        $entry-\u003egetAuthorId() ??\n        static::currentUser()-\u003eid,\n]));\n```\n\n`Entry::setAttributesFromRequest()` in [Entry.php](/D:/files/projects/cms-5.9.19/cms-5.9.19/src/elements/Entry.php):1124 extracts the new author IDs and applies them if `canChangeAuthor()` returns true:\n\n```php\nif (\n    ($authorIds !== null || $authorId !== null) \u0026\u0026\n    $this-\u003ecanChangeAuthor()\n) {\n    $this-\u003e_oldAuthorIds = $oldAuthorIds;\n    $this-\u003esetAuthorIds($authorIds);\n}\n```\n\n`canChangeAuthor()` at [Entry.php](/D:/files/projects/cms-5.9.19/cms-5.9.19/src/elements/Entry.php):2789 allows the author change when the current user can view peer entries and is already one of the existing authors:\n\n```php\nreturn (\n    empty($authorIds) ||\n    in_array($user-\u003eid, $authorIds) ||\n    $user-\u003ecan(\"changeAuthorForPeerEntries:$section-\u003euid\")\n);\n```\n\nAfter the author list is mutated, the controller does not re-check authorization. \n\nThis closes the exploit chain:\n\n1. External source: authenticated request to `entries/save-entry` with attacker-controlled `authors[]`.\n2. Trust boundary failure: authorization is checked on the pre-mutation entry state, not on the post-mutation author assignment.\n3. Privileged sink: the author relationship is rewritten in persistent storage.\n\nPreconditions derived from the source:\n\n1. The attacker is authenticated and can edit entry `345`.\n2. The attacker is among the existing authors of entry `345`, or otherwise satisfies `canChangeAuthor()` through the old author set.\n3. The attacker has `viewPeerEntries` for the section.\n4. User ID `1` exists and can be assigned as an author in that section.\n\nResult:\n\n1. `enforceEditEntryPermissions()` succeeds on the original entry state.\n2. `_populateEntryModel()` reads `authors[]=1` from the request body.\n3. `setAttributesFromRequest()` updates `authorIds` because `canChangeAuthor()` is evaluated against the old authorship state.\n4. `saveElement()` persists the change and `_saveAuthors()` rewrites the entry-author relation.\n5. Entry `345` now appears authored by user `1`.\n\n### Impact\n\nThis allows low-privileged users to falsify content ownership and alter the authorship of entries without having the dedicated author-management permission. The impact includes corrupted audit trails, misleading notifications, broken approval workflows, and unauthorized reassignment of content responsibility.",
  "id": "GHSA-qq2c-2q8j-jh27",
  "modified": "2026-07-02T18:45:28Z",
  "published": "2026-07-02T18:45:28Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/craftcms/cms/security/advisories/GHSA-qq2c-2q8j-jh27"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-50279"
    },
    {
      "type": "WEB",
      "url": "https://github.com/craftcms/cms/commit/9cc493be8b414d7116c7f2bc2a6d0926e73f1248"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/craftcms/cms"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Craft CMS: Authorship spoofing in `entries/save-entry` via pre-check/post-mutation authorization gap"
}

Mitigation
Architecture and Design
  • Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) to enforce the roles at the appropriate boundaries.
  • Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
Mitigation
Architecture and Design

Ensure that you perform access control checks related to your business logic. These checks may be different than the access control checks that you apply to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor.

Mitigation MIT-4.4
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
  • For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
Mitigation
Architecture and Design
  • For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page.
  • One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
Mitigation
System Configuration Installation

Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.

CAPEC-1: Accessing Functionality Not Properly Constrained by ACLs

In applications, particularly web applications, access to functionality is mitigated by an authorization framework. This framework maps Access Control Lists (ACLs) to elements of the application's functionality; particularly URL's for web apps. In the case that the administrator failed to specify an ACL for a particular element, an attacker may be able to access it with impunity. An attacker with the ability to access functionality not properly constrained by ACLs can obtain sensitive information and possibly compromise the entire application. Such an attacker can access resources that must be available only to users at a higher privilege level, can access management sections of the application, or can run queries for data that they otherwise not supposed to.

CAPEC-104: Cross Zone Scripting

An attacker is able to cause a victim to load content into their web-browser that bypasses security zone controls and gain access to increased privileges to execute scripting code or other web objects such as unsigned ActiveX controls or applets. This is a privilege elevation attack targeted at zone-based web-browser security.

CAPEC-127: Directory Indexing

An adversary crafts a request to a target that results in the target listing/indexing the content of a directory as output. One common method of triggering directory contents as output is to construct a request containing a path that terminates in a directory name rather than a file name since many applications are configured to provide a list of the directory's contents when such a request is received. An adversary can use this to explore the directory tree on a target as well as learn the names of files. This can often end up revealing test files, backup files, temporary files, hidden files, configuration files, user accounts, script contents, as well as naming conventions, all of which can be used by an attacker to mount additional attacks.

CAPEC-13: Subverting Environment Variable Values

The adversary directly or indirectly modifies environment variables used by or controlling the target software. The adversary's goal is to cause the target software to deviate from its expected operation in a manner that benefits the adversary.

CAPEC-17: Using Malicious Files

An attack of this type exploits a system's configuration that allows an adversary to either directly access an executable file, for example through shell access; or in a possible worst case allows an adversary to upload a file and then execute it. Web servers, ftp servers, and message oriented middleware systems which have many integration points are particularly vulnerable, because both the programmers and the administrators must be in synch regarding the interfaces and the correct privileges for each interface.

CAPEC-39: Manipulating Opaque Client-based Data Tokens

In circumstances where an application holds important data client-side in tokens (cookies, URLs, data files, and so forth) that data can be manipulated. If client or server-side application components reinterpret that data as authentication tokens or data (such as store item pricing or wallet information) then even opaquely manipulating that data may bear fruit for an Attacker. In this pattern an attacker undermines the assumption that client side tokens have been adequately protected from tampering through use of encryption or obfuscation.

CAPEC-402: Bypassing ATA Password Security

An adversary exploits a weakness in ATA security on a drive to gain access to the information the drive contains without supplying the proper credentials. ATA Security is often employed to protect hard disk information from unauthorized access. The mechanism requires the user to type in a password before the BIOS is allowed access to drive contents. Some implementations of ATA security will accept the ATA command to update the password without the user having authenticated with the BIOS. This occurs because the security mechanism assumes the user has first authenticated via the BIOS prior to sending commands to the drive. Various methods exist for exploiting this flaw, the most common being installing the ATA protected drive into a system lacking ATA security features (a.k.a. hot swapping). Once the drive is installed into the new system the BIOS can be used to reset the drive password.

CAPEC-45: Buffer Overflow via Symbolic Links

This type of attack leverages the use of symbolic links to cause buffer overflows. An adversary can try to create or manipulate a symbolic link file such that its contents result in out of bounds data. When the target software processes the symbolic link file, it could potentially overflow internal buffers with insufficient bounds checking.

CAPEC-5: Blue Boxing

This type of attack against older telephone switches and trunks has been around for decades. A tone is sent by an adversary to impersonate a supervisor signal which has the effect of rerouting or usurping command of the line. While the US infrastructure proper may not contain widespread vulnerabilities to this type of attack, many companies are connected globally through call centers and business process outsourcing. These international systems may be operated in countries which have not upgraded Telco infrastructure and so are vulnerable to Blue boxing. Blue boxing is a result of failure on the part of the system to enforce strong authorization for administrative functions. While the infrastructure is different than standard current applications like web applications, there are historical lessons to be learned to upgrade the access control for administrative functions.

{'xhtml:b': 'This attack pattern is included in CAPEC for historical purposes.'}

CAPEC-51: Poison Web Service Registry

SOA and Web Services often use a registry to perform look up, get schema information, and metadata about services. A poisoned registry can redirect (think phishing for servers) the service requester to a malicious service provider, provide incorrect information in schema or metadata, and delete information about service provider interfaces.

CAPEC-59: Session Credential Falsification through Prediction

This attack targets predictable session ID in order to gain privileges. The attacker can predict the session ID used during a transaction to perform spoofing and session hijacking.

CAPEC-60: Reusing Session IDs (aka Session Replay)

This attack targets the reuse of valid session ID to spoof the target system in order to gain privileges. The attacker tries to reuse a stolen session ID used previously during a transaction to perform spoofing and session hijacking. Another name for this type of attack is Session Replay.

CAPEC-647: Collect Data from Registries

An adversary exploits a weakness in authorization to gather system-specific data and sensitive information within a registry (e.g., Windows Registry, Mac plist). These contain information about the system configuration, software, operating system, and security. The adversary can leverage information gathered in order to carry out further attacks.

CAPEC-668: Key Negotiation of Bluetooth Attack (KNOB)

An adversary can exploit a flaw in Bluetooth key negotiation allowing them to decrypt information sent between two devices communicating via Bluetooth. The adversary uses an Adversary in the Middle setup to modify packets sent between the two devices during the authentication process, specifically the entropy bits. Knowledge of the number of entropy bits will allow the attacker to easily decrypt information passing over the line of communication.

CAPEC-76: Manipulating Web Input to File System Calls

An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.

CAPEC-77: Manipulating User-Controlled Variables

This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.

CAPEC-87: Forceful Browsing

An attacker employs forceful browsing (direct URL entry) to access portions of a website that are otherwise unreachable. Usually, a front controller or similar design pattern is employed to protect access to portions of a web application. Forceful browsing enables an attacker to access information, perform privileged operations and otherwise reach sections of the web application that have been improperly protected.