{"api_version":"1","generated_at":"2026-11-10T12:12:12+00:00","cve":"CVE-2026-120286","urls":{"html":"https://cve.report/CVE-2026-120286","api":"https://cve.report/api/cve/CVE-2026-120286.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-120286","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-120286"},"summary":{"title":"Missing authorization in device and deployment group page events allows view-role members to change devices and deployment groups","description":"Missing Authorization vulnerability in the device and deployment group pages in nerves-hub nerves_hub_web allows an authenticated organization member with the view role to change devices and deployment groups via LiveView events reserved for the manage role. The event handlers that add and delete device certificates, add and remove tags, overwrite or clear a device's manual location, remove a device from its deployment group, move matched devices into a deployment group or remove unmatched ones, import devices from a CSV, and start, retry or delete firmware delta builds carry out the change without calling authorized!/2, and the pages render the controls to every member.\n\nA view member can add a certificate that lets whoever holds its key connect as the device, delete a certificate so the device can no longer authenticate with it, and change which deployment group, and so which firmware release, a device receives. Everything stays within the organizations the member belongs to.\n\nThis issue affects nerves_hub: from 1.0.0 before 2.5.3.","state":"PUBLISHED","assigner":"EEF","published_at":"2026-11-10 11:16:41","updated_at":"2026-11-10 11:16:41"},"problem_types":["CWE-862","CWE-862 CWE-862 Missing Authorization"],"metrics":[{"version":"4.0","source":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","type":"Secondary","score":"5.3","severity":"MEDIUM","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N/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:X/R:X/V:X/RE:X/U:X","data":{"version":"4.0","vectorString":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N/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:X/R:X/V:X/RE:X/U:X","baseScore":5.3,"baseSeverity":"MEDIUM","attackVector":"NETWORK","attackComplexity":"LOW","attackRequirements":"NONE","privilegesRequired":"LOW","userInteraction":"NONE","vulnConfidentialityImpact":"LOW","vulnIntegrityImpact":"LOW","vulnAvailabilityImpact":"LOW","subConfidentialityImpact":"NONE","subIntegrityImpact":"LOW","subAvailabilityImpact":"NONE","exploitMaturity":"NOT_DEFINED","confidentialityRequirement":"NOT_DEFINED","integrityRequirement":"NOT_DEFINED","availabilityRequirement":"NOT_DEFINED","modifiedAttackVector":"NOT_DEFINED","modifiedAttackComplexity":"NOT_DEFINED","modifiedAttackRequirements":"NOT_DEFINED","modifiedPrivilegesRequired":"NOT_DEFINED","modifiedUserInteraction":"NOT_DEFINED","modifiedVulnConfidentialityImpact":"NOT_DEFINED","modifiedVulnIntegrityImpact":"NOT_DEFINED","modifiedVulnAvailabilityImpact":"NOT_DEFINED","modifiedSubConfidentialityImpact":"NOT_DEFINED","modifiedSubIntegrityImpact":"NOT_DEFINED","modifiedSubAvailabilityImpact":"NOT_DEFINED","Safety":"NOT_DEFINED","Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","valueDensity":"NOT_DEFINED","vulnerabilityResponseEffort":"NOT_DEFINED","providerUrgency":"NOT_DEFINED"}},{"version":"4.0","source":"CNA","type":"CVSS","score":"5.3","severity":"MEDIUM","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N","data":{"Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","Safety":"NOT_DEFINED","attackComplexity":"LOW","attackRequirements":"NONE","attackVector":"NETWORK","baseScore":5.3,"baseSeverity":"MEDIUM","privilegesRequired":"LOW","providerUrgency":"NOT_DEFINED","subAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"LOW","userInteraction":"NONE","valueDensity":"NOT_DEFINED","vectorString":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N","version":"4.0","vulnAvailabilityImpact":"LOW","vulnConfidentialityImpact":"LOW","vulnIntegrityImpact":"LOW","vulnerabilityResponseEffort":"NOT_DEFINED"}}],"references":[{"url":"https://github.com/nerves-hub/nerves_hub_web/security/advisories/GHSA-gxj7-m8x6-r644","name":"https://github.com/nerves-hub/nerves_hub_web/security/advisories/GHSA-gxj7-m8x6-r644","refsource":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://osv.dev/vulnerability/EEF-CVE-2026-120286","name":"https://osv.dev/vulnerability/EEF-CVE-2026-120286","refsource":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://github.com/nerves-hub/nerves_hub_web/commit/7b511764a468bb2c1f33945874faa86af2255c0c","name":"https://github.com/nerves-hub/nerves_hub_web/commit/7b511764a468bb2c1f33945874faa86af2255c0c","refsource":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://cna.erlef.org/cves/CVE-2026-120286.html","name":"https://cna.erlef.org/cves/CVE-2026-120286.html","refsource":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://github.com/nerves-hub/nerves_hub_web/commit/34ea112472a460319c1e1dec8ad0ffc37df05ffe","name":"https://github.com/nerves-hub/nerves_hub_web/commit/34ea112472a460319c1e1dec8ad0ffc37df05ffe","refsource":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-120286","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-120286","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"nerves-hub","product":"nerves_hub_web","version":"affected 1.0.0 2.5.3 other","platforms":[]},{"source":"CNA","vendor":"nerves-hub","product":"nerves_hub_web","version":"affected 1.0.0 2.5.3 semver","platforms":[]},{"source":"CNA","vendor":"nerves-hub","product":"nerves_hub_web","version":"affected 7b511764a468bb2c1f33945874faa86af2255c0c 34ea112472a460319c1e1dec8ad0ffc37df05ffe git","platforms":[]}],"timeline":[],"solutions":[{"source":"CNA","title":"","value":"Upgrading does not remove a certificate that a view member already added. After upgrading, review each device's certificates and delete any you do not recognize.","time":"","lang":"en"}],"workarounds":[{"source":"CNA","title":"","value":"No configuration closes the hole. Until the upgrade, give the view role only to people you would trust with the manage role on that organization's devices.","time":"","lang":"en"}],"exploits":[],"credits":[{"source":"CNA","value":"arbor-s","lang":"en"},{"source":"CNA","value":"arbor-s","lang":"en"},{"source":"CNA","value":"Josh Kalderimis","lang":"en"},{"source":"CNA","value":"Jonatan Männchen / EEF","lang":"en"}],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":null,"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"collectionURL":"https://ghcr.io","cpes":["cpe:2.3:a:nerves-hub:nerves_hub_web:*:*:*:*:*:*:*:*"],"defaultStatus":"unaffected","modules":["'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab'","'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab'","'Elixir.NervesHubWeb.Live.DeploymentGroups.Show'","'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary'"],"packageName":"nerves-hub/nerves-hub","packageURL":"pkg:oci/nerves-hub?repository_url=ghcr.io%2Fnerves-hub","product":"nerves_hub_web","programFiles":["lib/nerves_hub_web/components/device_page/settings_tab.ex","lib/nerves_hub_web/components/device_page/details_tab.ex","lib/nerves_hub_web/live/deployment_groups/show.ex","lib/nerves_hub_web/components/deployment_group_page/summary.ex"],"programRoutines":[{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':handle_progress/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Live.DeploymentGroups.Show':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_progress/3"}],"vendor":"nerves-hub","versions":[{"lessThan":"2.5.3","status":"affected","version":"1.0.0","versionType":"other"}]},{"cpes":["cpe:2.3:a:nerves-hub:nerves_hub_web:*:*:*:*:*:*:*:*"],"defaultStatus":"unaffected","modules":["'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab'","'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab'","'Elixir.NervesHubWeb.Live.DeploymentGroups.Show'","'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary'"],"packageName":"nerves_hub","packageURL":"pkg:otp/nerves_hub?repository_url=https:%2F%2Fgithub.com%2Fnerves-hub%2Fnerves_hub_web&vcs_url=git%20https:%2F%2Fgithub.com%2Fnerves-hub%2Fnerves_hub_web.git","product":"nerves_hub_web","programFiles":["lib/nerves_hub_web/components/device_page/settings_tab.ex","lib/nerves_hub_web/components/device_page/details_tab.ex","lib/nerves_hub_web/live/deployment_groups/show.ex","lib/nerves_hub_web/components/deployment_group_page/summary.ex"],"programRoutines":[{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':handle_progress/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Live.DeploymentGroups.Show':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_progress/3"}],"repo":"https://github.com/nerves-hub/nerves_hub_web","vendor":"nerves-hub","versions":[{"lessThan":"2.5.3","status":"affected","version":"1.0.0","versionType":"semver"}]},{"collectionURL":"https://github.com","cpes":["cpe:2.3:a:nerves-hub:nerves_hub_web:*:*:*:*:*:*:*:*"],"defaultStatus":"unaffected","modules":["'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab'","'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab'","'Elixir.NervesHubWeb.Live.DeploymentGroups.Show'","'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary'"],"packageName":"nerves-hub/nerves_hub_web","packageURL":"pkg:github/nerves-hub/nerves_hub_web","product":"nerves_hub_web","programFiles":["lib/nerves_hub_web/components/device_page/settings_tab.ex","lib/nerves_hub_web/components/device_page/details_tab.ex","lib/nerves_hub_web/live/deployment_groups/show.ex","lib/nerves_hub_web/components/deployment_group_page/summary.ex"],"programRoutines":[{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.SettingsTab':handle_progress/3"},{"name":"'Elixir.NervesHubWeb.Components.DevicePage.DetailsTab':hooked_event/3"},{"name":"'Elixir.NervesHubWeb.Live.DeploymentGroups.Show':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_event/3"},{"name":"'Elixir.NervesHubWeb.Components.DeploymentGroupPage.Summary':handle_progress/3"}],"repo":"https://github.com/nerves-hub/nerves_hub_web","vendor":"nerves-hub","versions":[{"lessThan":"34ea112472a460319c1e1dec8ad0ffc37df05ffe","status":"affected","version":"7b511764a468bb2c1f33945874faa86af2255c0c","versionType":"git"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:a:nerves-hub:nerves_hub_web:*:*:*:*:*:*:*:*","versionEndExcluding":"2.5.3","versionStartIncluding":"1.0.0","vulnerable":true}],"negate":false,"operator":"OR"}],"operator":"AND"}],"credits":[{"lang":"en","type":"finder","value":"arbor-s"},{"lang":"en","type":"reporter","value":"arbor-s"},{"lang":"en","type":"remediation developer","value":"Josh Kalderimis"},{"lang":"en","type":"coordinator","value":"Jonatan Männchen / EEF"}],"dateAssigned":"2026-11-09T22:27:53.000Z","descriptions":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>Missing Authorization vulnerability in the device and deployment group pages in nerves-hub nerves_hub_web allows an authenticated organization member with the <code>view</code> role to change devices and deployment groups via LiveView events reserved for the <code>manage</code> role. The event handlers that add and delete device certificates, add and remove tags, overwrite or clear a device's manual location, remove a device from its deployment group, move matched devices into a deployment group or remove unmatched ones, import devices from a CSV, and start, retry or delete firmware delta builds carry out the change without calling <code>authorized!/2</code>, and the pages render the controls to every member.</p>\n<p>A <code>view</code> member can add a certificate that lets whoever holds its key connect as the device, delete a certificate so the device can no longer authenticate with it, and change which deployment group, and so which firmware release, a device receives. Everything stays within the organizations the member belongs to.</p>\n<p>This issue affects nerves_hub: from 1.0.0 before 2.5.3.</p>"},{"base64":false,"type":"text/markdown","value":"Missing Authorization vulnerability in the device and deployment group pages in nerves-hub nerves_hub_web allows an authenticated organization member with the `view` role to change devices and deployment groups via LiveView events reserved for the `manage` role. The event handlers that add and delete device certificates, add and remove tags, overwrite or clear a device's manual location, remove a device from its deployment group, move matched devices into a deployment group or remove unmatched ones, import devices from a CSV, and start, retry or delete firmware delta builds carry out the change without calling `authorized!/2`, and the pages render the controls to every member.\n\nA `view` member can add a certificate that lets whoever holds its key connect as the device, delete a certificate so the device can no longer authenticate with it, and change which deployment group, and so which firmware release, a device receives. Everything stays within the organizations the member belongs to.\n\nThis issue affects nerves_hub: from 1.0.0 before 2.5.3."}],"value":"Missing Authorization vulnerability in the device and deployment group pages in nerves-hub nerves_hub_web allows an authenticated organization member with the view role to change devices and deployment groups via LiveView events reserved for the manage role. The event handlers that add and delete device certificates, add and remove tags, overwrite or clear a device's manual location, remove a device from its deployment group, move matched devices into a deployment group or remove unmatched ones, import devices from a CSV, and start, retry or delete firmware delta builds carry out the change without calling authorized!/2, and the pages render the controls to every member.\n\nA view member can add a certificate that lets whoever holds its key connect as the device, delete a certificate so the device can no longer authenticate with it, and change which deployment group, and so which firmware release, a device receives. Everything stays within the organizations the member belongs to.\n\nThis issue affects nerves_hub: from 1.0.0 before 2.5.3."}],"impacts":[{"capecId":"CAPEC-1","descriptions":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>An organization member with the view role can add or delete a device's certificates, change its tags and location, and move devices into or out of deployment groups, which changes the firmware release they receive. An added certificate lets whoever holds its key connect as the device and persists after the member leaves. Everything stays within the organizations the member belongs to.</p>"},{"base64":false,"type":"text/markdown","value":"An organization member with the view role can add or delete a device's certificates, change its tags and location, and move devices into or out of deployment groups, which changes the firmware release they receive. An added certificate lets whoever holds its key connect as the device and persists after the member leaves. Everything stays within the organizations the member belongs to."}],"value":"An organization member with the view role can add or delete a device's certificates, change its tags and location, and move devices into or out of deployment groups, which changes the firmware release they receive. An added certificate lets whoever holds its key connect as the device and persists after the member leaves. Everything stays within the organizations the member belongs to."}]}],"metrics":[{"cvssV4_0":{"Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","Safety":"NOT_DEFINED","attackComplexity":"LOW","attackRequirements":"NONE","attackVector":"NETWORK","baseScore":5.3,"baseSeverity":"MEDIUM","privilegesRequired":"LOW","providerUrgency":"NOT_DEFINED","subAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"LOW","userInteraction":"NONE","valueDensity":"NOT_DEFINED","vectorString":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N","version":"4.0","vulnAvailabilityImpact":"LOW","vulnConfidentialityImpact":"LOW","vulnIntegrityImpact":"LOW","vulnerabilityResponseEffort":"NOT_DEFINED"},"format":"CVSS","scenarios":[{"lang":"en","value":"GENERAL"}]}],"problemTypes":[{"descriptions":[{"cweId":"CWE-862","description":"CWE-862 Missing Authorization","lang":"en","type":"CWE"}]}],"providerMetadata":{"dateUpdated":"2026-11-10T10:44:07.907Z","orgId":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","shortName":"EEF"},"references":[{"name":"Users with the ‘view’ role can change devices and deployment groups and read local shell output","tags":["vendor-advisory","related"],"url":"https://github.com/nerves-hub/nerves_hub_web/security/advisories/GHSA-gxj7-m8x6-r644"},{"name":"EEF CNA record for CVE-2026-120286","tags":["related"],"url":"https://cna.erlef.org/cves/CVE-2026-120286.html"},{"name":"OSV record EEF-CVE-2026-120286","tags":["related"],"url":"https://osv.dev/vulnerability/EEF-CVE-2026-120286"},{"name":"Introducing commit 7b51176 in nerves-hub/nerves_hub_web","tags":["related"],"url":"https://github.com/nerves-hub/nerves_hub_web/commit/7b511764a468bb2c1f33945874faa86af2255c0c"},{"name":"Fix commit 34ea112 in nerves-hub/nerves_hub_web","tags":["patch"],"url":"https://github.com/nerves-hub/nerves_hub_web/commit/34ea112472a460319c1e1dec8ad0ffc37df05ffe"}],"solutions":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>Upgrading does not remove a certificate that a <code>view</code> member already added. After upgrading, review each device's certificates and delete any you do not recognize.</p>"},{"base64":false,"type":"text/markdown","value":"Upgrading does not remove a certificate that a `view` member already added. After upgrading, review each device's certificates and delete any you do not recognize."}],"value":"Upgrading does not remove a certificate that a view member already added. After upgrading, review each device's certificates and delete any you do not recognize."}],"source":{"discovery":"UNKNOWN"},"title":"Missing authorization in device and deployment group page events allows view-role members to change devices and deployment groups","workarounds":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>No configuration closes the hole. Until the upgrade, give the <code>view</code> role only to people you would trust with the <code>manage</code> role on that organization's devices.</p>"},{"base64":false,"type":"text/markdown","value":"No configuration closes the hole. Until the upgrade, give the `view` role only to people you would trust with the `manage` role on that organization's devices."}],"value":"No configuration closes the hole. Until the upgrade, give the view role only to people you would trust with the manage role on that organization's devices."}],"x_proofOfConcept":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<ol>\n<li>Create deployment group <code>canary</code> with conditions matching tag <code>beta</code>.</li>\n<li>Create <code>device_outside_match</code> in the same product with tag <code>beta</code> and no deployment group, and <code>device_inside_mismatch</code> in deployment group <code>canary</code> with tag <code>foo</code>.</li>\n<li>Sign in as a member of the organization with the <code>view</code> role and open <code>/org/&lt;org&gt;/&lt;product&gt;/deployment_groups/canary</code>.</li>\n<li>Click <code>Move device(s)</code>: <code>device_outside_match</code> is now in <code>canary</code>. Click <code>Remove device(s)</code>: <code>device_inside_mismatch</code> no longer has a deployment group.</li>\n<li>As the same member, open a device in the product and add a tag. The tag is saved.</li>\n<li>On the device's settings tab, delete a certificate, or upload a self-signed one. The change is saved, and a client presenting the uploaded certificate connects as the device.</li>\n</ol>"},{"base64":false,"type":"text/markdown","value":"1. Create deployment group `canary` with conditions matching tag `beta`.\n2. Create `device_outside_match` in the same product with tag `beta` and no deployment group, and `device_inside_mismatch` in deployment group `canary` with tag `foo`.\n3. Sign in as a member of the organization with the `view` role and open `/org/<org>/<product>/deployment_groups/canary`.\n4. Click `Move device(s)`: `device_outside_match` is now in `canary`. Click `Remove device(s)`: `device_inside_mismatch` no longer has a deployment group.\n5. As the same member, open a device in the product and add a tag. The tag is saved.\n6. On the device's settings tab, delete a certificate, or upload a self-signed one. The change is saved, and a client presenting the uploaded certificate connects as the device."}],"value":"* Create deployment group canary with conditions matching tag beta.\n* Create device_outside_match in the same product with tag beta and no deployment group, and device_inside_mismatch in deployment group canary with tag foo.\n* Sign in as a member of the organization with the view role and open /org/<org>/<product>/deployment_groups/canary.\n* Click Move device(s): device_outside_match is now in canary. Click Remove device(s): device_inside_mismatch no longer has a deployment group.\n* As the same member, open a device in the product and add a tag. The tag is saved.\n* On the device's settings tab, delete a certificate, or upload a self-signed one. The change is saved, and a client presenting the uploaded certificate connects as the device."}],"x_technicalAnalysis":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>The dashboard reads the member's role into <code>current_scope</code> when a page mounts, and each privileged event handler is expected to call <code>authorized!/2</code> with the permission it needs, all of which resolve to the <code>manage</code> role in <code>lib/nerves_hub_web/helpers/authorization.ex</code>. These handlers never do:</p>\n<p><strong>Device settings tab</strong> (<code>NervesHubWeb.Components.DevicePage.SettingsTab</code>): <code>hooked_event/3</code> for <code>delete-certificate</code>, and <code>handle_progress/3</code> for the <code>certificate</code> upload, which should require <code>device:update</code>.</p>\n<p><strong>Device details tab</strong> (<code>NervesHubWeb.Components.DevicePage.DetailsTab</code>): <code>hooked_event/3</code> for <code>add-tag</code>, <code>remove-tag</code>, <code>save-location-changes</code> and <code>clear-manual-location-information</code> (<code>device:update</code>), and <code>remove-from-deployment-group</code> (<code>device:set-deployment-group</code>).</p>\n<p><strong>Deployment group page</strong> (<code>NervesHubWeb.Live.DeploymentGroups.Show</code> and <code>NervesHubWeb.Components.DeploymentGroupPage.Summary</code>): <code>handle_event/3</code> for <code>move-matched-devices-to-deployment-group</code> and <code>remove-unmatched-devices-from-deployment-group</code>, and <code>handle_progress/3</code> for the <code>device_csv</code> upload (<code>device:set-deployment-group</code>), plus <code>generate-firmware-deltas</code>, <code>retry_delta</code> and <code>delete_delta</code> (<code>deployment_group:update</code>).</p>\n<p>The pages show every one of these controls to <code>view</code> members, so each change takes a click, and a client can send the events directly over the LiveView socket regardless.</p>"},{"base64":false,"type":"text/markdown","value":"The dashboard reads the member's role into `current_scope` when a page mounts, and each privileged event handler is expected to call `authorized!/2` with the permission it needs, all of which resolve to the `manage` role in `lib/nerves_hub_web/helpers/authorization.ex`. These handlers never do:\n\n**Device settings tab** (`NervesHubWeb.Components.DevicePage.SettingsTab`): `hooked_event/3` for `delete-certificate`, and `handle_progress/3` for the `certificate` upload, which should require `device:update`.\n\n**Device details tab** (`NervesHubWeb.Components.DevicePage.DetailsTab`): `hooked_event/3` for `add-tag`, `remove-tag`, `save-location-changes` and `clear-manual-location-information` (`device:update`), and `remove-from-deployment-group` (`device:set-deployment-group`).\n\n**Deployment group page** (`NervesHubWeb.Live.DeploymentGroups.Show` and `NervesHubWeb.Components.DeploymentGroupPage.Summary`): `handle_event/3` for `move-matched-devices-to-deployment-group` and `remove-unmatched-devices-from-deployment-group`, and `handle_progress/3` for the `device_csv` upload (`device:set-deployment-group`), plus `generate-firmware-deltas`, `retry_delta` and `delete_delta` (`deployment_group:update`).\n\nThe pages show every one of these controls to `view` members, so each change takes a click, and a client can send the events directly over the LiveView socket regardless."}],"value":"The dashboard reads the member's role into current_scope when a page mounts, and each privileged event handler is expected to call authorized!/2 with the permission it needs, all of which resolve to the manage role in lib/nerves_hub_web/helpers/authorization.ex. These handlers never do:\n\nDevice settings tab (NervesHubWeb.Components.DevicePage.SettingsTab): hooked_event/3 for delete-certificate, and handle_progress/3 for the certificate upload, which should require device:update.\n\nDevice details tab (NervesHubWeb.Components.DevicePage.DetailsTab): hooked_event/3 for add-tag, remove-tag, save-location-changes and clear-manual-location-information (device:update), and remove-from-deployment-group (device:set-deployment-group).\n\nDeployment group page (NervesHubWeb.Live.DeploymentGroups.Show and NervesHubWeb.Components.DeploymentGroupPage.Summary): handle_event/3 for move-matched-devices-to-deployment-group and remove-unmatched-devices-from-deployment-group, and handle_progress/3 for the device_csv upload (device:set-deployment-group), plus generate-firmware-deltas, retry_delta and delete_delta (deployment_group:update).\n\nThe pages show every one of these controls to view members, so each change takes a click, and a client can send the events directly over the LiveView socket regardless."}]}},"cveMetadata":{"assignerOrgId":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","assignerShortName":"EEF","cveId":"CVE-2026-120286","datePublished":"2026-11-10T10:44:07.907Z","dateReserved":"2026-11-04T17:15:01.545Z","dateUpdated":"2026-11-10T10:44:07.907Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-11-10 11:16:41","lastModifiedDate":"2026-11-10 11:16:41","problem_types":["CWE-862","CWE-862 CWE-862 Missing Authorization"],"metrics":{"cvssMetricV40":[{"source":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","type":"Secondary","cvssData":{"version":"4.0","vectorString":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:L/SA:N/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:X/R:X/V:X/RE:X/U:X","baseScore":5.3,"baseSeverity":"MEDIUM","attackVector":"NETWORK","attackComplexity":"LOW","attackRequirements":"NONE","privilegesRequired":"LOW","userInteraction":"NONE","vulnConfidentialityImpact":"LOW","vulnIntegrityImpact":"LOW","vulnAvailabilityImpact":"LOW","subConfidentialityImpact":"NONE","subIntegrityImpact":"LOW","subAvailabilityImpact":"NONE","exploitMaturity":"NOT_DEFINED","confidentialityRequirement":"NOT_DEFINED","integrityRequirement":"NOT_DEFINED","availabilityRequirement":"NOT_DEFINED","modifiedAttackVector":"NOT_DEFINED","modifiedAttackComplexity":"NOT_DEFINED","modifiedAttackRequirements":"NOT_DEFINED","modifiedPrivilegesRequired":"NOT_DEFINED","modifiedUserInteraction":"NOT_DEFINED","modifiedVulnConfidentialityImpact":"NOT_DEFINED","modifiedVulnIntegrityImpact":"NOT_DEFINED","modifiedVulnAvailabilityImpact":"NOT_DEFINED","modifiedSubConfidentialityImpact":"NOT_DEFINED","modifiedSubIntegrityImpact":"NOT_DEFINED","modifiedSubAvailabilityImpact":"NOT_DEFINED","Safety":"NOT_DEFINED","Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","valueDensity":"NOT_DEFINED","vulnerabilityResponseEffort":"NOT_DEFINED","providerUrgency":"NOT_DEFINED"}}]},"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"120286","Ordinal":"1","Title":"Missing authorization in device and deployment group page events","CVE":"CVE-2026-120286","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"120286","Ordinal":"1","NoteData":"Missing Authorization vulnerability in the device and deployment group pages in nerves-hub nerves_hub_web allows an authenticated organization member with the view role to change devices and deployment groups via LiveView events reserved for the manage role. The event handlers that add and delete device certificates, add and remove tags, overwrite or clear a device's manual location, remove a device from its deployment group, move matched devices into a deployment group or remove unmatched ones, import devices from a CSV, and start, retry or delete firmware delta builds carry out the change without calling authorized!/2, and the pages render the controls to every member.\n\nA view member can add a certificate that lets whoever holds its key connect as the device, delete a certificate so the device can no longer authenticate with it, and change which deployment group, and so which firmware release, a device receives. Everything stays within the organizations the member belongs to.\n\nThis issue affects nerves_hub: from 1.0.0 before 2.5.3.","Type":"Description","Title":"Missing authorization in device and deployment group page events"}]}}}