# Craft CMS's mass assignment via id in newAttributes during bulk duplicate overwrites existing elements

Craft CMS bulk-duplicate action lets a low-privileged author pass an arbitrary id in newAttributes, overwriting any other element row via UPDATE instead of INSERT.

- Payout: Research
- Severity: high
- Program: Craft CMS
- Found by: adrgs
- Disclosed: 2026-07-02
- CVE: CVE-2026-50281
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-x5m4-g2cq-52pq
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-x5m4-g2cq-52pq
- Tags: area:web domain:web impact:integrity kind:research platform:ghsa sev:high tech:php technique:source-review vuln:access-control vuln:business-logic

**Target:** ElementsController bulk-duplicate element action
**Root cause:** Top-level id/canonicalId guard only inspects the request body, while the separate newAttributes array is filtered by safeAttributes() (which includes id) and passed to Craft::configure(), overwriting the clone's id=null reset so saveElement() UPDATEs an existing row.
**Steps:**
1. Authenticate as an author with permission to duplicate an entry you own.
2. POST to the bulk duplicate element action with `elements` containing your entry and `newAttributes` containing `{"id": <victim element id>, "title": "...", "slug": "..."}`.
3. beforeAction() sees no top-level `id`/`canonicalId` and allows the request.
4. Collection::only($element->safeAttributes()) keeps `id`; duplicateElement() clones, sets id=null, then Craft::configure() overwrites it with the attacker id.
5. saveElement() runs UPDATE on the victim's row, writing attacker title/slug/authorId/postDate/uid.
**How found:** Noticed the top-level id guard only checks the request body, then traced newAttributes through Collection::only(safeAttributes()) and Craft::configure() to see the id=null reset being overwritten.
**Exploitation:** Enumerate or predict target element IDs, then submit a single bulk-duplicate request with newAttributes.id set to the victim's ID; the victim entry's content and ownership fields are replaced with the attacker's values.
**Escalation:** Element table inheritance means entries, categories and users sharing the Entry element table can be targeted, so a single low-priv author can corrupt content across the install.
**Insight:** When a controller blocks a sensitive key at the top level, check every nested/alternate parameter that reaches the same model configuration path; safeAttributes() often includes primary keys, so only() filters are not a security boundary.

