CVE-2026-32633
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
CVE-2026-32633 is a critical vulnerability (CVSS 9.1) in Nicolargo Glances, published March 16, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.49%, the 42nd percentile. Fixed in glances 4.5.2.
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
9.1
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
CVE-2026-32633- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
EUVDEUVD-2026-12926
9.1
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
EUVD-2026-12926- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r297-p3v4-wp8m
9.1
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Summary
In Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret.
If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance.
Details
The Browser API route simply returns the raw servers list:
# glances/outputs/glances_restful_api.py:799-805
def _api_servers_list(self):
self.__update_servers_list()
return GlancesJSONResponse(self.servers_list.get_servers_list() if self.servers_list else [])
The main API router is only protected when the front instance itself was started with --password. Otherwise there are no authentication dependencies at all:
# glances/outputs/glances_restful_api.py:475-480
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix)
The Glances web server binds to 0.0.0.0 by default:
# glances/main.py:425-427
parser.add_argument(
'--bind',
default='0.0.0.0',
dest='bind_address',
)
During Central Browser polling, server entries are modified in-place and gain a uri field:
# glances/servers_list.py:141-148
def __update_stats(self, server):
server['uri'] = self.get_uri(server)
...
if server['protocol'].lower() == 'rpc':
self.__update_stats_rpc(server['uri'], server)
elif server['protocol'].lower() == 'rest' and not import_requests_error_tag:
self.__update_stats_rest(f"{server['uri']}/api/{__apiversion__}", server)
For protected servers, get_uri() loads the saved password from the [passwords] section (or the default password), hashes it, and embeds it directly in the URI:
# glances/servers_list.py:119-130
def get_uri(self, server):
if server['password'] != "":
if server['status'] == 'PROTECTED':
clear_password = self.password.get_password(server['name'])
if clear_password is not None:
server['password'] = self.password.get_hash(clear_password)
uri = 'http://{}:{}@{}:{}'.format(
server['username'],
server['password'],
server['name'],
server['port'],
)
else:
uri = 'http://{}:{}'.format(server['name'], server['port'])
return uri
Password lookup falls back to a global default:
# glances/password_list.py:55-58
try:
return self._password_dict[host]
except (KeyError, TypeError):
return self._password_dict['default']
The sample configuration explicitly supports browser-wide default password reuse:
# conf/glances.conf:656-663
[passwords]
# localhost=abc
# default=defaultpassword
The secret embedded in uri is not the cleartext password, but it is still a reusable Glances authentication credential. Client connections send that pbkdf2-derived hash over HTTP Basic authentication:
# glances/password.py:72-74,94
# For Glances client, get the password (confirm=False, clear=True):
# 2) the password is hashed with SHA-pbkdf2_hmac (only SHA string transit
password = password_hash
# glances/client.py:56-57
if args.password != "":
self.uri = f'http://{args.username}:{args.password}@{args.client}:{args.port}'
The Browser WebUI also consumes that raw uri directly and redirects the user to it:
// glances/outputs/static/js/Browser.vue:83-103…
- Record
GHSA-r297-p3v4-wp8m- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
NVD
9.1
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
CVE-2026-32633- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSV
9.1
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
CVE-2026-32633- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-32633
9.1
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
DEBIAN-CVE-2026-32633- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-r297-p3v4-wp8m
9.1
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Summary
In Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret.
If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance.
Details
The Browser API route simply returns the raw servers list:
# glances/outputs/glances_restful_api.py:799-805
def _api_servers_list(self):
self.__update_servers_list()
return GlancesJSONResponse(self.servers_list.get_servers_list() if self.servers_list else [])
The main API router is only protected when the front instance itself was started with --password. Otherwise there are no authentication dependencies at all:
# glances/outputs/glances_restful_api.py:475-480
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix)
The Glances web server binds to 0.0.0.0 by default:
# glances/main.py:425-427
parser.add_argument(
'--bind',
default='0.0.0.0',
dest='bind_address',
)
During Central Browser polling, server entries are modified in-place and gain a uri field:
# glances/servers_list.py:141-148
def __update_stats(self, server):
server['uri'] = self.get_uri(server)
...
if server['protocol'].lower() == 'rpc':
self.__update_stats_rpc(server['uri'], server)
elif server['protocol'].lower() == 'rest' and not import_requests_error_tag:
self.__update_stats_rest(f"{server['uri']}/api/{__apiversion__}", server)
For protected servers, get_uri() loads the saved password from the [passwords] section (or the default password), hashes it, and embeds it directly in the URI:
# glances/servers_list.py:119-130
def get_uri(self, server):
if server['password'] != "":
if server['status'] == 'PROTECTED':
clear_password = self.password.get_password(server['name'])
if clear_password is not None:
server['password'] = self.password.get_hash(clear_password)
uri = 'http://{}:{}@{}:{}'.format(
server['username'],
server['password'],
server['name'],
server['port'],
)
else:
uri = 'http://{}:{}'.format(server['name'], server['port'])
return uri
Password lookup falls back to a global default:
# glances/password_list.py:55-58
try:
return self._password_dict[host]
except (KeyError, TypeError):
return self._password_dict['default']
The sample configuration explicitly supports browser-wide default password reuse:
# conf/glances.conf:656-663
[passwords]
# localhost=abc
# default=defaultpassword
The secret embedded in uri is not the cleartext password, but it is still a reusable Glances authentication credential. Client connections send that pbkdf2-derived hash over HTTP Basic authentication:
# glances/password.py:72-74,94
# For Glances client, get the password (confirm=False, clear=True):
# 2) the password is hashed with SHA-pbkdf2_hmac (only SHA string transit
password = password_hash
# glances/client.py:56-57
if args.password != "":
self.uri = f'http://{args.username}:{args.password}@{args.client}:{args.port}'
The Browser WebUI also consumes that raw uri directly and redirects the user to it:
// glances/outputs/static/js/Browser.vue:83-103…
- Record
GHSA-r297-p3v4-wp8m- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSVPYSEC-2026-343
9.1
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Summary
In Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret.
If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance.
Details
The Browser API route simply returns the raw servers list:
# glances/outputs/glances_restful_api.py:799-805
def _api_servers_list(self):
self.__update_servers_list()
return GlancesJSONResponse(self.servers_list.get_servers_list() if self.servers_list else [])
The main API router is only protected when the front instance itself was started with --password. Otherwise there are no authentication dependencies at all:
# glances/outputs/glances_restful_api.py:475-480
if self.args.password:
router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])
else:
router = APIRouter(prefix=self.url_prefix)
The Glances web server binds to 0.0.0.0 by default:
# glances/main.py:425-427
parser.add_argument(
'--bind',
default='0.0.0.0',
dest='bind_address',
)
During Central Browser polling, server entries are modified in-place and gain a uri field:
# glances/servers_list.py:141-148
def __update_stats(self, server):
server['uri'] = self.get_uri(server)
...
if server['protocol'].lower() == 'rpc':
self.__update_stats_rpc(server['uri'], server)
elif server['protocol'].lower() == 'rest' and not import_requests_error_tag:
self.__update_stats_rest(f"{server['uri']}/api/{__apiversion__}", server)
For protected servers, get_uri() loads the saved password from the [passwords] section (or the default password), hashes it, and embeds it directly in the URI:
# glances/servers_list.py:119-130
def get_uri(self, server):
if server['password'] != "":
if server['status'] == 'PROTECTED':
clear_password = self.password.get_password(server['name'])
if clear_password is not None:
server['password'] = self.password.get_hash(clear_password)
uri = 'http://{}:{}@{}:{}'.format(
server['username'],
server['password'],
server['name'],
server['port'],
)
else:
uri = 'http://{}:{}'.format(server['name'], server['port'])
return uri
Password lookup falls back to a global default:
# glances/password_list.py:55-58
try:
return self._password_dict[host]
except (KeyError, TypeError):
return self._password_dict['default']
The sample configuration explicitly supports browser-wide default password reuse:
# conf/glances.conf:656-663
[passwords]
# localhost=abc
# default=defaultpassword
The secret embedded in uri is not the cleartext password, but it is still a reusable Glances authentication credential. Client connections send that pbkdf2-derived hash over HTTP Basic authentication:
# glances/password.py:72-74,94
# For Glances client, get the password (confirm=False, clear=True):
# 2) the password is hashed with SHA-pbkdf2_hmac (only SHA string transit
password = password_hash
# glances/client.py:56-57
if args.password != "":
self.uri = f'http://{args.username}:{args.password}@{args.client}:{args.port}'
The Browser WebUI also consumes that raw uri directly and redirects the user to it:
// glances/outputs/static/js/Browser.vue:83-103…
- Record
PYSEC-2026-343- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-32633
9.1
Glances is an open-source system cross-platform monitoring tool. Prior to version 4.5.2, in Central Browser mode, the /api/4/serverslist endpoint returns raw server objects from GlancesServersList.get_servers_list(). Those objects are mutated in-place during background polling and can contain a uri field with embedded HTTP Basic credentials for downstream Glances servers, using the reusable pbkdf2-derived Glances authentication secret. If the front Glances Browser/API instance is started without --password, which is supported and common for internal network deployments, /api/4/serverslist is completely unauthenticated. Any network user who can reach the Browser API can retrieve reusable credentials for protected downstream Glances servers once they have been polled by the browser instance. Version 4.5.2 fixes the issue.
- Record
UBUNTU-CVE-2026-32633- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:10415-1 No score
glances-common-4.5.2-1.1 on GA media
These are all security issues fixed in the glances-common-4.5.2-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:10415-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
glancesPyPI |
through 4.5.2-dev01 | 4.5.2 |
glancesDebian:12 |
All versions, plus listed versions 3.3.1.1+dfsg-13.4.0.3+dfsg-14.0.5+dfsg-14.1.2.1+dfsg-14.2.1+dfsg-1 Show 9 moreShow less4.3.0.8+dfsg-14.3.1+dfsg-14.3.3+dfsg-14.5.1+dfsg-14.5.2+dfsg-14.5.3.2+dfsg-14.5.4+dfsg-14.5.5+dfsg-14.5.6+dfsg-1 |
None known |
glancesDebian:13 |
All versions, plus listed versions 4.3.1+dfsg-14.3.3+dfsg-14.5.1+dfsg-14.5.2+dfsg-14.5.3.2+dfsg-14.5.4+dfsg-14.5.5+dfsg-14.5.6+dfsg-1 |
None known |
glancesDebian:14 |
before 4.5.2+dfsg-1, plus listed versions 4.3.1+dfsg-14.3.3+dfsg-14.5.1+dfsg-1 |
4.5.2+dfsg-1 |
glancesPyPI |
before 4.5.2, plus listed versions 1.3.11.3.21.3.31.3.41.3.5 Show 45 moreShow less1.3.61.3.71.41.4.11.4.1.11.4.21.4.2.11.51.5.11.5.21.61.6.11.71.7.11.7.21.7.31.7.41.7.51.7.61.7.72.02.0.12.12.1.12.1.22.102.112.11.12.22.2.12.32.42.4.12.4.22.52.5.12.62.6.12.6.22.72.7.12.82.8.12.8.22.8.3 |
4.5.2 |
glancesUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 2.3-1build12.3-1ubuntu0.1~esm1 |
None known |
glancesUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 2.10-22.11.1-12.11.1-22.11.1-32.11.1-3ubuntu0.1~esm1 |
None known |
glancesUbuntu:Pro:20.04:LTS |
All versions, plus listed versions 3.1.0-13.1.1-13.1.3-13.1.3-1ubuntu0.1~esm1 |
None known |
glancesUbuntu:22.04:LTS |
All versions, plus listed versions 3.1.5-13.2.3.1+dfsg-13.2.4.2+dfsg-1 |
None known |
glancesUbuntu:24.04:LTS |
All versions, plus listed versions 3.4.0.3+dfsg-1 |
None known |
Show 4 moreShow less
| Package | Affected | Fixed |
|---|---|---|
glancesUbuntu:25.10 |
All versions, plus listed versions 4.3.0.8+dfsg-14.3.1+dfsg-1 |
None known |
glancesUbuntu:26.10 |
All versions, plus listed versions 4.3.3+dfsg-14.5.4+dfsg-14.5.5+dfsg-14.5.6+dfsg-1 |
None known |
glancesUbuntu:26.04:LTS |
All versions, plus listed versions 4.3.1+dfsg-14.3.3+dfsg-1 |
None known |
python-GlancesopenSUSE:Tumbleweed |
before 4.5.2-1.1 | 4.5.2-1.1 |
History
| When | Changed | Sources |
|---|---|---|
| 2026-11-02 | created | CVE List, EUVD, GitHub Advisories, NVD, OSV |
References
github.com/nicolargo/glances/security/advisories/GHSA-r297-p3v4-wp8m
github.com/nicolargo/glances/commit/879ef8688ffa1630839549751d3c7ef9961d361e
github.com/nicolargo/glances/releases/tag/v4.5.2
nvd.nist.gov/vuln/detail/CVE-2026-32633
github.com/pypa/advisory-database/tree/main/vulns/glances/PYSEC-2026-343.yaml
pypi.org/project/glances
Show 14 moreShow less
github.com/advisories/GHSA-r297-p3v4-wp8m
github.com/CVEProject/cvelistV5/tree/main/cves/2026/32xxx/CVE-2026-32633.json
security-tracker.debian.org/tracker/CVE-2026-32633
github.com/nicolargo/glances
ubuntu.com/security/CVE-2026-32633
cve.org/CVERecord?id=CVE-2026-32633
suse.com/security/cve/CVE-2026-32596
suse.com/security/cve/CVE-2026-32608
suse.com/security/cve/CVE-2026-32609
suse.com/security/cve/CVE-2026-32610
suse.com/security/cve/CVE-2026-32611
suse.com/security/cve/CVE-2026-32632
suse.com/security/cve/CVE-2026-32633
suse.com/security/cve/CVE-2026-32634
Left out here: 81 versions and the rest of 3 source descriptions. The JSON record has them.