{"id":"PYSEC-2026-3664","summary":"Glances: as_dict_secure() Value-Level Bypass Leaks Credentials in URL Values via /api/4/config","details":"## Summary\n\nGlances provides `as_dict_secure()` explicitly designed for unauthenticated API access, with a docstring stating it returns \"a sanitised copy of the configuration dict\" where \"Sensitive keys in remaining sections are replaced by '********'\". However, the implementation only checks KEY names against a regex pattern and never inspects VALUE content. The documented `[ip]` config section supports `public_api` (URL), `public_username` (login), and `public_password` (password). While `public_password` is correctly masked, both `public_api` (when containing embedded credentials like `https://user:pass@host/`) and `public_username` are returned in full to unauthenticated users via `GET /api/4/config`.\n\n## Affected Versions\n\nGlances latest (Docker: `nicolargo/glances:latest`)\n\n## Root Cause\n\nIn `glances/config.py`, `as_dict_secure()`:\n```python\n_SECURE_SENSITIVE_KEY_RE = re.compile(r\"password|token|secret|api_key|apikey|ssl_keyfile\", re.IGNORECASE)\n\ndef as_dict_secure(self):\n    \"\"\"Return a sanitised copy of the configuration dict.\n    Intended for unauthenticated API access.\n    - Sensitive keys in remaining sections are replaced by '********'.\n    \"\"\"\n    sanitized = {}\n    for section, options in self.as_dict().items():\n        if section in _SECURE_BLOCKED_SECTIONS: continue\n        sanitized[section] = {\n            key: \"********\" if _SECURE_SENSITIVE_KEY_RE.search(key) else value\n            for key, value in options.items()\n        }\n    return sanitized\n```\n\nIn `glances/outputs/glances_restful_api.py`:\n```python\n# Line 1294\nargs_json = self.config.as_dict() if self.args.password else self.config.as_dict_secure()\n```\n\nThe `[ip]` config section documents: `public_api` (URL), `public_username` (login), `public_password` (password).\n- `public_password` → matches \"password\" → masked ✓\n- `public_api` → no match → returned in full (contains `user:pass@` in URL) ✗\n- `public_username` → no match → returned in full ✗\n\n## Impact\n\n- Unauthenticated credential disclosure via `GET /api/4/config` or `GET /api/4/config/ip`\n- `as_dict_secure()` exists specifically to protect credentials in no-auth mode but fails to mask `public_username` and credential-bearing URLs in `public_api`\n\n## Prerequisites\n\n- Glances in web server mode without `--password` (default, no auth)\n- `glances.conf` `[ip]` section with `public_api` containing embedded credentials and/or `public_username` set\n\n## Environment\n\n- Glances latest (Docker: `nicolargo/glances:latest`)\n- Remote Docker lab at `http://10.140.200.102:8080`\n\n## Reproduction Steps\n\n```bash\ndocker run -d --name glances-test -p 8080:61208 -e GLANCES_OPT='-w' nicolargo/glances:latest\nsleep 20\ndocker exec glances-test sed -i 's|public_api=https://ipv4.ipleak.net/json/|public_api=https://admin:secret123@ipv4.ipleak.net/json/|' /etc/glances/glances.conf\ndocker exec glances-test sed -i 's|#public_username=\u003cmyname\u003e|public_username=myname|' /etc/glances/glances.conf\ndocker exec glances-test sed -i 's|#public_password=\u003cmysecret\u003e|public_password=mysecret|' /etc/glances/glances.conf\ndocker restart glances-test\nsleep 15\ncurl -s \"$TARGET/api/4/config/ip\"\n# Returns: {\"public_api\": \"https://admin:secret123@...\", \"public_username\": \"myname\", \"public_password\": \"********\"}\n```\n\n## Evidence\n\nSee `C:/Tools/glances-config-leak-evidence.txt`.\n\n## Dedup Check\n\n- GHSA-gfc2-9qmw-w7vh covers CORS but NOT value-level credential leak\n- No existing GHSA covers `as_dict_secure()` value-level filtering gap\n- 13 published GHSA, none covering this issue\n\n## Suggested Remediation\n\nAdd \"username\" and \"login\" to sensitive key pattern, and check values for embedded credentials in URLs.\n\n## Disclosure Timeline\n\n- 2026-07-28: Vulnerability discovered and verified via Docker deployment\n\n## Reporter\n\nGitHub username: Todor","aliases":["CVE-2026-68520","GHSA-4h34-v6r8-mmjc"],"modified":"2026-08-19T12:45:04.268775299Z","published":"2026-08-19T11:56:26.971395Z","references":[{"type":"WEB","url":"https://github.com/nicolargo/glances/security/advisories/GHSA-4h34-v6r8-mmjc"},{"type":"WEB","url":"https://github.com/nicolargo/glances/commit/8d0f8276c2abd2e9d400bd6c84bdfba0dfcab065"},{"type":"PACKAGE","url":"https://github.com/nicolargo/glances"},{"type":"WEB","url":"https://github.com/nicolargo/glances/releases/tag/v4.5.6"},{"type":"PACKAGE","url":"https://pypi.org/project/glances"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-4h34-v6r8-mmjc"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-68520"}],"affected":[{"package":{"name":"glances","ecosystem":"PyPI","purl":"pkg:pypi/glances"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.5.6"}]}],"versions":["1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.7","1.4","1.4.1","1.4.1.1","1.4.2","1.4.2.1","1.5","1.5.1","1.5.2","1.6","1.6.1","1.7","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","2.0","2.0.1","2.1","2.1.1","2.1.2","2.10","2.11","2.11.1","2.2","2.2.1","2.3","2.4","2.4.1","2.4.2","2.5","2.5.1","2.6","2.6.1","2.6.2","2.7","2.7.1","2.8","2.8.1","2.8.2","2.8.3","2.8.4","2.8.5","2.8.6","2.8.7","2.8.8","2.9.0","2.9.1","3.0","3.0.1","3.0.2","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.4.1","3.1.5","3.1.6","3.1.6.1","3.1.6.2","3.1.7","3.2.0","3.2.1","3.2.2","3.2.3","3.2.3.1","3.2.4","3.2.4.1","3.2.4.2","3.2.5","3.2.6.1","3.2.6.2","3.2.6.3","3.2.6.4","3.2.7","3.3.0","3.3.0.1","3.3.0.2","3.3.0.3","3.3.0.4","3.3.1","3.3.1.1","3.4.0","3.4.0.1","3.4.0.2","3.4.0.3","3.4.0.4","3.4.0.5","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.1.0","4.1.1","4.1.2","4.2.0","4.2.1","4.3.0","4.3.0.1","4.3.0.3","4.3.0.4","4.3.0.5","4.3.0.6","4.3.0.7","4.3.0.8","4.3.1","4.3.2","4.3.3","4.4.0","4.4.1","4.5.0","4.5.0.1","4.5.0.2","4.5.0.3","4.5.0.4","4.5.0.5","4.5.1","4.5.2","4.5.3","4.5.4","4.5.5"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/glances/PYSEC-2026-3664.yaml"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N"}]}