Skip to main content
HDWSec
Medium CVE-2026-88989GHSA-3qh3-54qg-gpq3

Silverstripe CMS: Missing canCreate() Check in GridFieldDetailForm leading to Unauthorised Record Creation

Severity
Medium
CVSS score
4.3CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
CVE number(s)
CVE-2026-88989GHSA-3qh3-54qg-gpq3
Vendor
Silverstripe
Product
Silverstripe CMS (silverstripe/framework, src/Forms/GridField/GridFieldDetailForm_ItemRequest.php - doSave())
Affected version(s)
silverstripe/framework 6.2.12 and earlier
Fixed version(s)
6.2.13, released 2026-10-28
Vulnerability type
Missing Authorization (CWE-862) on the new-record save path: canEdit() enforced, canCreate() never checked
Researchers
Jean-Jamil KHALIFÉ

Presentation

Silverstripe CMS is an open-source PHP content management system developed by Silverstripe Ltd. Most of its back office is built from GridFields: a list of records whose detail view, GridFieldDetailForm, is the form used both to edit an existing record and to create a new one. Access to records is governed by distinct permission methods on each model, notably canEdit() for modifying a record and canCreate() for adding one.

HDW Sec found that the server-side save path of that form enforced only canEdit(), never canCreate(). A CMS user allowed to edit records of a given model, but not to create them, could therefore create new records by sending the save request directly.

Issue(s)

  • GridFieldDetailForm_ItemRequest::doSave() (src/Forms/GridField/GridFieldDetailForm_ItemRequest.php) computes $isNewRecord = $this->record->ID == 0, then applies a single permission gate, canEdit(), before writing the record. For a new record the relevant authorisation is canCreate(), which the method never called.
  • The canCreate() checks that did exist were interface-only: the “Add” button is hidden and the item form is made read-only when the check fails. makeReadonly() does not remove the doSave form action, which stays dispatchable, and the request handler still accepts it, so a crafted POST of action_doSave to .../item/new/ItemEditForm reaches the save path regardless of the read-only interface.
  • Reproduced live on a self-hosted Silverstripe 6.2.2 lab: a model whose canEdit() returns true and whose canCreate() returns false gets a new record written through the exact decision path of doSave(), and the method body was checked by reflection to contain no canCreate() call.
  • Scope: any model exposed through a GridField detail form whose create permission is stricter than its edit permission, which is precisely what custom permission codes are used for in real deployments. Core models whose two checks are identical were not affected, since there is no privilege gap to cross.
  • Affected versions: silverstripe/framework before 6.2.13. The vendor rated the issue medium, 4.3.

References

Our R&D hunts for vulnerabilities.

Zero-day research, reverse engineering, coordinated disclosure: discover our R&D team.