{"id":"CVE-2026-107360","kind":"vulnerability","aliases":["CVE-2026-107360"],"related":[],"title":"rubygem-safemode: compound assignment bypasses Jail allow-list in templates","description":"A flaw was found in rubygem-safemode. Compound assignment expressions in sandboxed code are evaluated without mediating method calls through the Jail allow-list. An authenticated attacker who can supply template content can invoke arbitrary no-argument methods on objects exposed to the template renderer without Jail mediation, including destructive operations such as host deletion and disclosure of non-allow-listed object state.","summary":"safemode is a Ruby gem that runs untrusted template code inside a sandbox. Compound assignment expressions skip the Jail allow-list check, so an authenticated user who can supply template content can call arbitrary no-argument methods on exposed objects, including destructive ones and reads of non-allow-listed state.","severity":"critical","cvss":9.6,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"safemode","fixed":[],"affected":"unknown, no fixed version published","ecosystem":"rubygems"},{"name":"Red Hat Satellite 6","fixed":[],"affected":"affected per Red Hat, versions unspecified","ecosystem":"vendor"}],"ecosystems":[],"tags":["auth-required","foreman","package","red-hat-satellite","ruby","rubygems","safemode","self-hosted"],"not_affected_if":["no-user-templates","safemode-not-used","trusted-template-authors-only"],"how_to_check":"Check Gemfile.lock for safemode (bundle list | grep safemode; on Foreman/Satellite: rpm -q rubygem-safemode). Then see whether untrusted users can edit templates (Foreman: roles with edit_provisioning_templates etc.). No fixed version is published, so any version in use should be treated as exposed.","fix":"unknown: no fixed safemode release published yet (Red Hat Bugzilla status NEW). Mitigation: restrict template edit privileges to trusted administrators and avoid exposing privileged ActiveRecord objects to untrusted template authors.","status":"open","published_at":"2026-11-12T20:18:14+00:00","first_seen_at":"2026-11-12T20:40:22+00:00","triaged_at":"2026-11-12T20:41:47+00:00","updated_at":"2026-11-12T20:44:10+00:00","category":"package","confidence":0.75,"triage":{"at":"2026-11-12T20:41:47Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"rubygem-safemode: compound assignment bypasses Jail allow-list in templates","impact":"high","summary":"safemode is a Ruby gem that runs untrusted template code inside a sandbox. Compound assignment expressions skip the Jail allow-list check, so an authenticated user who can supply template content can call arbitrary no-argument methods on exposed objects, including destructive ones and reads of non-allow-listed state.","audience":"developers","category":"package","nicknames":[],"who_cares":["ruby","rubygems","safemode"],"confidence":0.6,"fix_status":"unknown","needs_auth":"yes","worst_case":"attacker can delete hosts and read non-allow-listed object state","analyst_note":"Find affected and fixed safemode versions in the NVD entry or the upstream repository, and confirm whether the flaw needs authentication.","how_to_check":"- Check whether the Gemfile or Gemfile.lock includes `safemode` and which version is locked.\n- Look for code that passes user-supplied template content to the safemode Jail renderer.","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["no-user-templates","safemode-not-used"],"who_is_affected":"Applications that use the safemode gem to render user-supplied templates are exposed, because the sandbox does not mediate compound assignment calls. Applications that only render their own fixed templates, or do not use safemode, can skip it. The sources do not give affected or fixed versions.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"unknown","severity_if_unknown":"critical"},"cost_usd":0.000734,"input_tokens":4562,"output_tokens":555,"severity_before":"critical"},"analyst_status":"done","analyst_note":"Find affected and fixed safemode versions in the NVD entry or the upstream repository, and confirm whether the flaw needs authentication.","search":"'-107360':15A,18A '-2026':14A,17A '6':23A 'allow':9A,59B,89B,116C,155C 'allow-list':8A,58B,115C 'arbitrari':73B,128C 'argument':76B,131C 'assign':5A,53B,101C 'attack':120C 'auth':25B 'auth-requir':24B 'authent':64B,119C 'bypass':6A 'call':72B,111C 'check':61B 'code':48B,105C 'compound':4A,52B,100C 'content':70B,125C 'cve':13A,16A 'delet':149C 'destruct':82B,144C 'disclosur':151C 'evalu':107C 'expos':79B,135C 'express':54B,102C 'flaw':93C 'foreman':27B 'found':95C 'gem':43B 'hat':21A,31B 'host':38B,148C 'includ':81B,143C 'insid':49B 'invok':127C 'jail':7A,57B,114C,141C 'list':10A,60B,90B,117C,156C 'mediat':109C,142C 'method':77B,110C,132C 'no-argu':74B,129C 'non':88B,154C 'non-allow-list':87B,153C 'object':80B,134C,157C 'one':83B 'oper':145C 'packag':28B 'read':85B 'red':20A,30B 'red-hat-satellit':29B 'render':139C 'requir':26B 'rubi':33B,42B 'rubygem':2A,34B,98C 'rubygem-safemod':1A,97C 'run':45B 'safemod':3A,35B,39B,99C 'safemode':19A 'sandbox':51B,104C 'satellit':32B 'satellite':22A 'self':37B 'self-host':36B 'skip':55B 'state':91B,158C 'suppli':68B,123C 'templat':12A,47B,69B,124C,138C 'untrust':46B 'user':65B 'without':108C,140C","nicknames":[],"mitigations":[],"who_affected":"Apps that render user-written templates through the safemode gem, notably Foreman and Red Hat Satellite 6 where template editors can reach host objects. A logged-in user who can edit templates can call methods the Jail allow-list blocks, such as Host#destroy, and read hidden state. Skip if only trusted admins edit templates or you do not use safemode.","tier":"B","verified":{"fix":{"at":"2026-11-12T20:44:10Z","by":"analyst","doc":"https://access.redhat.com/security/cve/CVE-2026-107360","run_id":3775},"mitigations":{"at":"2026-11-12T20:44:10Z","by":"analyst","doc":"https://access.redhat.com/security/cve/CVE-2026-107360","run_id":3775}},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":["hatsatellite6","redhatsatellite6","safemode"],"ptokens":["hat","red","safemode","satellite"],"labels":["authrequired","critical","foreman","package","redhatsatellite","ruby","rubygems","safemode","selfhosted"],"campaign_type":null,"search_a":"'-107360':15A,18A '-2026':14A,17A '6':23A 'allow':9A 'allow-list':8A 'assign':5A 'bypass':6A 'compound':4A 'cve':13A,16A 'hat':21A 'jail':7A 'list':10A 'red':20A 'rubygem':2A 'rubygem-safemod':1A 'safemod':3A 'safemode':19A 'satellite':22A 'templat':12A","search_b":"'allow':59B,89B 'allow-list':58B 'arbitrari':73B 'argument':76B 'assign':53B 'auth':25B 'auth-requir':24B 'authent':64B 'call':72B 'check':61B 'code':48B 'compound':52B 'content':70B 'destruct':82B 'expos':79B 'express':54B 'foreman':27B 'gem':43B 'hat':31B 'host':38B 'includ':81B 'insid':49B 'jail':57B 'list':60B,90B 'method':77B 'no-argu':74B 'non':88B 'non-allow-list':87B 'object':80B 'one':83B 'packag':28B 'read':85B 'red':30B 'red-hat-satellit':29B 'requir':26B 'rubi':33B,42B 'rubygem':34B 'run':45B 'safemod':35B,39B 'sandbox':51B 'satellit':32B 'self':37B 'self-host':36B 'skip':55B 'state':91B 'suppli':68B 'templat':47B,69B 'untrust':46B 'user':65B","search_c":"'allow':116C,155C 'allow-list':115C 'arbitrari':128C 'argument':131C 'assign':101C 'attack':120C 'authent':119C 'call':111C 'code':105C 'compound':100C 'content':125C 'delet':149C 'destruct':144C 'disclosur':151C 'evalu':107C 'expos':135C 'express':102C 'flaw':93C 'found':95C 'host':148C 'includ':143C 'invok':127C 'jail':114C,141C 'list':117C,156C 'mediat':109C,142C 'method':110C,132C 'no-argu':129C 'non':154C 'non-allow-list':153C 'object':134C,157C 'oper':145C 'render':139C 'rubygem':98C 'rubygem-safemod':97C 'safemod':99C 'sandbox':104C 'state':158C 'suppli':123C 'templat':124C,138C 'without':108C,140C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T20:18:14+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N","cvss_by":"secalert@redhat.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-107360","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107360","severity":null,"published_at":"2026-11-12T20:18:14+00:00","modified_at":"2026-11-12T20:18:15+00:00","first_seen_at":"2026-11-12T20:40:22+00:00","fetched_at":"2026-11-12T20:40:22+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-107360:3775","url":"https://access.redhat.com/security/cve/CVE-2026-107360","severity":null,"published_at":"2026-11-12T20:44:10+00:00","modified_at":"2026-11-12T20:44:10+00:00","first_seen_at":"2026-11-12T20:44:10+00:00","fetched_at":"2026-11-12T20:44:10+00:00","note":"Red Hat CVE page + Bugzilla 2547645 (status NEW, no fixed version): op_asgn AST nodes skip .to_jail; needs authenticated low-priv template editor (PR:L); Foreman/Satellite confirmed (@host.destroy). No fixed safemode version published as of 2026-11-12; affected range unknown. Separate from CVE-2026-96658 (fixed in safemode 2.0.1), do not assume 2.0.1 fixes this.","cites":["https://access.redhat.com/security/cve/CVE-2026-107360","https://bugzilla.redhat.com/show_bug.cgi?id=2547645"]}],"documents":[{"id":138440,"url":"https://access.redhat.com/security/cve/CVE-2026-107360","title":"Red Hat CVE-2026-107360","kind":"vendor","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null},{"id":138441,"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2547645","title":"Red Hat Bugzilla 2547645: safemode Jail allow-list bypass via op-assign","kind":"advisory","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"describes","confidence":null,"note":null}],"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"}