{"id":"CVE-2026-120295","kind":"vulnerability","aliases":["CVE-2026-120295"],"related":[],"title":"NervesHub: view-only user can move devices into another organization","description":"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.\n\nA 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.\n\nThis issue affects nerves_hub: from 1.0.0 before 2.5.3.","summary":"NervesHub's devices page lets a user with only view access in one organization move devices into a second organization where they hold the view role, because the target product check accepts any membership role. Moved devices receive that organization's firmware and download URLs, which a view-only user could not otherwise obtain.","severity":"high","cvss":7.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["elixir","iot","nerves-hub","package","self-hosted"],"not_affected_if":["default-config","single-organization"],"how_to_check":"- Check the installed `nerves_hub` version in your `mix.lock` or release; affected from `1.0.0` before `2.5.3`.\n- Review which users hold the view role in one organization and the manage role in another, since that combination is needed to exploit it.","fix":"- `nerves_hub` `2.5.3`","status":"open","published_at":"2026-11-10T11:16:41+00:00","first_seen_at":"2026-11-10T11:21:35+00:00","triaged_at":"2026-11-10T11:22:02+00:00","updated_at":"2026-11-10T11:22:02+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-10T11:22:02Z","model":"claude-haiku-5-5","output":{"fix":"- `nerves_hub` `2.5.3`","reach":"network","title":"NervesHub: view-only user can move devices into another organization","impact":"medium","summary":"NervesHub's devices page lets a user with only view access in one organization move devices into a second organization where they hold the view role, because the target product check accepts any membership role. Moved devices receive that organization's firmware and download URLs, which a view-only user could not otherwise obtain.","audience":"businesses","category":"package","nicknames":[],"who_cares":["nerves-hub","self-hosted","elixir","iot"],"confidence":0.7,"fix_status":"available","needs_auth":"yes","worst_case":"View-only user gains firmware download access and control of moved devices.","analyst_note":"","how_to_check":"- Check the installed `nerves_hub` version in your `mix.lock` or release; affected from `1.0.0` before `2.5.3`.\n- Review which users hold the view role in one organization and the manage role in another, since that combination is needed to exploit it.","plain_action":"","product_name":"nerves_hub","needs_analyst":false,"not_affected_if":["single-organization","default-config"],"who_is_affected":"Teams running NervesHub for managing devices across more than one organization, where some users have view-only access in one organization and manage access in another. A single-organization deployment or one where all users hold manage rights is not exposed through this path. The attacker needs an authenticated account with the manage role in one organization and view in another.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000757,"input_tokens":4835,"output_tokens":546,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-120295':14A,17A '-2026':13A,16A '1.0.0':261C '2.5.3':263C 'accept':58B 'access':37B 'action':132C 'add':193C 'affect':257C 'allow':98C 'alreadi':249C 'anoth':10A,115C 'api':180C 'authent':100C 'author':83C 'belong':250C 'bulk':89C 'cannot':238C,243C 'certif':216C 'chang':170C,244C 'check':57B,149C,195C 'control':246C 'could':78B 'cve':12A,15A 'deploy':223C 'devic':8A,29B,42B,63B,87C,118C,128C,167C,173C,179C,200C,211C,247C 'download':70B,232C 'earlier':191C 'elixir':18B 'enter':208C 'event':137C 'firmwar':68B,229C 'fix':192C 'group':224C 'hold':49B 'host':26B 'hub':22B,94C,96C,259C 'id/2':147C 'incorrect':82C 'iot':19B 'issu':256C 'join':217C 'keep':212C 'key':214C 'leav':201C 'let':31B 'look':140C 'manag':104C,184C 'match':222C 'member':155C 'membership':60B 'move':7A,41B,62B,90C,117C,127C,166C,182C,210C 'move-devices-product':165C 'nerv':21B,93C,95C,258C 'nerves-hub':20B,92C 'nerveshub':1A,27B 'nerveshub.products.get':145C 'nerveshubweb.live.devices.index':139C 'obtain':81B,240C 'one':39B,107C,206C 'organ':11A,40B,46B,66B,108C,122C,160C,175C,188C,198C,220C,254C 'otherwis':80B,239C 'packag':23B 'page':30B,88C 'product':56B,124C,131C,136C,142C,158C,168C,177C 'receiv':64B 'requir':183C 'role':52B,61B,105C,113C,163C,237C 'second':45B,121C 'select':172C 'self':25B 'self-host':24B 'sent':227C 'target':55B,135C,187C,219C 'target-product':134C 'url':71B,233C 'user':5A,33B,77B,101C,152C,242C 'via':125C 'view':3A,36B,51B,75B,112C,236C 'view-on':2A,74B 'vulner':84C 'web':97C","nicknames":[],"mitigations":[],"who_affected":"Teams running NervesHub for managing devices across more than one organization, where some users have view-only access in one organization and manage access in another. A single-organization deployment or one where all users hold manage rights is not exposed through this path. The attacker needs an authenticated account with the manage role in one organization and view in another.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["elixir","high","iot","nerveshub","package","selfhosted"],"campaign_type":null,"search_a":"'-120295':14A,17A '-2026':13A,16A 'anoth':10A 'cve':12A,15A 'devic':8A 'move':7A 'nerveshub':1A 'organ':11A 'user':5A 'view':3A 'view-on':2A","search_b":"'accept':58B 'access':37B 'check':57B 'could':78B 'devic':29B,42B,63B 'download':70B 'elixir':18B 'firmwar':68B 'hold':49B 'host':26B 'hub':22B 'iot':19B 'let':31B 'membership':60B 'move':41B,62B 'nerv':21B 'nerves-hub':20B 'nerveshub':27B 'obtain':81B 'one':39B 'organ':40B,46B,66B 'otherwis':80B 'packag':23B 'page':30B 'product':56B 'receiv':64B 'role':52B,61B 'second':45B 'self':25B 'self-host':24B 'target':55B 'url':71B 'user':33B,77B 'view':36B,51B,75B 'view-on':74B","search_c":"'1.0.0':261C '2.5.3':263C 'action':132C 'add':193C 'affect':257C 'allow':98C 'alreadi':249C 'anoth':115C 'api':180C 'authent':100C 'author':83C 'belong':250C 'bulk':89C 'cannot':238C,243C 'certif':216C 'chang':170C,244C 'check':149C,195C 'control':246C 'deploy':223C 'devic':87C,118C,128C,167C,173C,179C,200C,211C,247C 'download':232C 'earlier':191C 'enter':208C 'event':137C 'firmwar':229C 'fix':192C 'group':224C 'hub':94C,96C,259C 'id/2':147C 'incorrect':82C 'issu':256C 'join':217C 'keep':212C 'key':214C 'leav':201C 'look':140C 'manag':104C,184C 'match':222C 'member':155C 'move':90C,117C,127C,166C,182C,210C 'move-devices-product':165C 'nerv':93C,95C,258C 'nerves-hub':92C 'nerveshub.products.get':145C 'nerveshubweb.live.devices.index':139C 'obtain':240C 'one':107C,206C 'organ':108C,122C,160C,175C,188C,198C,220C,254C 'otherwis':239C 'page':88C 'product':124C,131C,136C,142C,158C,168C,177C 'requir':183C 'role':105C,113C,163C,237C 'second':121C 'select':172C 'sent':227C 'target':135C,187C,219C 'target-product':134C 'url':233C 'user':101C,152C,242C 'via':125C 'view':112C,236C 'vulner':84C 'web':97C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-10T10:39:13+00:00","kev":null,"cvss_vector":"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/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","cvss_by":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-120295","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-120295","severity":null,"published_at":"2026-11-10T11:16:41+00:00","modified_at":"2026-11-10T11:16:41+00:00","first_seen_at":"2026-11-10T11:21:35+00:00","fetched_at":"2026-11-10T11:21:35+00:00","note":null}],"documents":[{"id":114612,"url":"https://github.com/nerves-hub/nerves_hub_web/commit/1bc8be875ab6b1eb904e5ff60c8a1421c5c700fa","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":114613,"url":"https://github.com/nerves-hub/nerves_hub_web/commit/79743ef08f7f801617b653fd09f37c01ed9b4be0","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":114614,"url":"https://github.com/nerves-hub/nerves_hub_web/commit/adaeefdb7a835525482588f43332ef988cc448c7","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":114615,"url":"https://github.com/nerves-hub/nerves_hub_web/security/advisories/GHSA-2j7r-q3vm-8j34","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-10T10:39:13+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}