CVE-2026-120295
Incorrect authorization in the devices page bulk move allows view-role members to move devices into another organization and receive its firmware
Incorrect Authorization vulnerability in the devices page bulk move in nerves-hub nerves_hub_web allows an authenticated user with the manage role in one organization and only the view role in another to move devices into the second organization's product via the "Move device(s) to product" action. The target-product event in NervesHubWeb.Live.Devices.Index looks the product up with NervesHub.Products.get_by_id/2, which checks that the user is a member of the product's organization at any role, and move-devices-product then changes each selected device's organization and product. The device API's move requires manage in the target organization, and an earlier fix added the check on the organization the devices leave but not on the one they enter. A moved device keeps its key and certificate, joins the target organization's matching deployment groups, and is sent their firmware with a download URL, which the view role cannot otherwise obtain. The user cannot change or control devices that already belong to the other organization. This issue affects nerves_hub: from 1.0.0 before 2.5.3.
Fixes and workarounds
Fix
Every move is recorded in the target product's audit log as "User moved device to : ". After upgrading, review the audit_logs rows with resource type NervesHub.Products.Product and a description containing "moved device" whose actor does not hold the manage or admin role in that organization, and move or remove the devices they brought in. Roles may have changed since a move, and entries older than the retention period are gone when TRUNCATE_AUDIT_LOGS_ENABLED is on.
Source: CNA: EEFFix
The reporting source identifies this reference as a patch. Check the advisory for affected versions and supported release branches.
Source: CNA: EEFAffected products and versions
| Product | Versions | Authority |
|---|---|---|
| nerves_hub_web nerves-hub nerves-hub/nerves-hub
oci |
≥ 1.0.0; < 2.5.3 (affected, other)
Other versions: unaffected |
CNA: EEF |
| nerves_hub_web nerves-hub nerves_hub
otp |
≥ 1.0.0; < 2.5.3 (affected, semver)
Other versions: unaffected |
CNA: EEF |
| nerves_hub_web nerves-hub nerves-hub/nerves_hub_web
github |
≥ adaeefdb7a835525482588f43332ef988cc448c7; < * (affected, git) ≥ 79743ef08f7f801617b653fd09f37c01ed9b4be0; < 1bc8be875ab6b1eb904e5ff60c8a1421c5c700fa (affected, git) Other versions: unaffected |
CNA: EEF |
Version ranges are source assertions. Check the vendor advisory and your installed configuration before determining exposure.
CVSS assessments
| Version / score | Vector | Authority |
|---|---|---|
| 4.0 / 7.1 high |
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N | CNA: EEF |
Exploit evidence
No exploit evidence in collected sources. This is not proof of no exploitation.
References
- https://github.com/nerves-hub/nerves_hub_web/security/advisories/GHSA-2j7r-q3vm-8j34CNA: EEF · vendor-advisory, related
- https://cna.erlef.org/cves/CVE-2026-120295.htmlCNA: EEF · related
- https://osv.dev/vulnerability/EEF-CVE-2026-120295CNA: EEF · related
- https://github.com/nerves-hub/nerves_hub_web/commit/adaeefdb7a835525482588f43332ef988cc448c7CNA: EEF · related
- https://github.com/nerves-hub/nerves_hub_web/commit/79743ef08f7f801617b653fd09f37c01ed9b4be0CNA: EEF · related
- https://github.com/nerves-hub/nerves_hub_web/commit/1bc8be875ab6b1eb904e5ff60c8a1421c5c700faCNA: EEF · patch
For agents and automation
Read public disclosures for free as Markdown or JSON. Compatible browsers also expose native WebMCP tools to search disclosures, read this page, and discover API access.
Use the ontology-linked Cyber API with x402 pay per request, or a Y2 Pro or Elite API key with the intel:cyber scope.
Endpoints and access details
https://api.y2.dev/api/v2/cyber/cveshttps://api.y2.dev/api/v2/cyber/cves/{cveId}
A workspace owner or admin can create a Pro or Elite API key. Send Authorization: Bearer <Y2_API_KEY> from your trusted agent runtime.
For x402, omit Authorization and read the HTTP 402 payment challenge before signing a retry. Public browser tools do not make payments.