VYPR
High severityNVD Advisory· Published Mar 10, 2026· Updated Mar 10, 2026

Glances Exposes Unauthenticated Configuration Secrets

CVE-2026-30928

Description

Glances is an open-source system cross-platform monitoring tool. Prior to 4.5.1, the /api/4/config REST API endpoint returns the entire parsed Glances configuration file (glances.conf) via self.config.as_dict() with no filtering of sensitive values. The configuration file contains credentials for all configured backend services including database passwords, API tokens, JWT signing keys, and SSL key passwords. This vulnerability is fixed in 4.5.1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
GlancesPyPI
< 4.5.14.5.1

Affected products

1

Patches

1
306a7136154b

Merge commit from fork

https://github.com/nicolargo/glancesNicolas HennionMar 7, 2026via ghsa
2 files changed · +32 3
  • glances/config.py+29 0 modified
    @@ -17,6 +17,19 @@
     from glances.globals import BSD, LINUX, MACOS, SUNOS, WINDOWS, ConfigParser, NoOptionError, NoSectionError, system_exec
     from glances.logger import logger
     
    +# Sections entirely blocked from the secure view
    +_SECURE_BLOCKED_SECTIONS = frozenset(
    +    {
    +        "passwords",
    +    }
    +)
    +
    +# Key name patterns redacted in any section
    +_SECURE_SENSITIVE_KEY_RE = re.compile(
    +    r"password|token|secret|api_key|apikey|ssl_keyfile",
    +    re.IGNORECASE,
    +)
    +
     
     def user_config_dir():
         r"""Return a list of per-user config dir (full path).
    @@ -286,6 +299,22 @@ def as_dict(self):
                     dictionary[section][option] = self.parser.get(section, option)
             return dictionary
     
    +    def as_dict_secure(self):
    +        """Return a sanitised copy of the configuration dict.
    +
    +        Intended for unauthenticated API access.
    +        - Blocked sections are omitted entirely.
    +        - Sensitive keys in remaining sections are replaced by '********'.
    +        """
    +        sanitized = {}
    +        for section, options in self.as_dict().items():
    +            if section in _SECURE_BLOCKED_SECTIONS:
    +                continue
    +            sanitized[section] = {
    +                key: "********" if _SECURE_SENSITIVE_KEY_RE.search(key) else value for key, value in options.items()
    +            }
    +        return sanitized
    +
         def sections(self):
             """Return a list of all sections."""
             return self.parser.sections()
    
  • glances/outputs/glances_restful_api.py+3 3 modified
    @@ -1165,7 +1165,7 @@ def _api_config(self):
             """
             try:
                 # Get the RAW value of the config' dict
    -            args_json = self.config.as_dict()
    +            args_json = self.config.as_dict() if self.args.password else self.config.as_dict_secure()
             except Exception as e:
                 raise HTTPException(status.HTTP_404_NOT_FOUND, f"Cannot get config ({str(e)})")
             else:
    @@ -1179,7 +1179,7 @@ def _api_config_section(self, section: str):
             HTTP/400 if item is not found
             HTTP/404 if others error
             """
    -        config_dict = self.config.as_dict()
    +        config_dict = self.config.as_dict() if self.args.password else self.config.as_dict_secure()
             if section not in config_dict:
                 raise HTTPException(status.HTTP_400_BAD_REQUEST, f"Unknown configuration item {section}")
     
    @@ -1199,7 +1199,7 @@ def _api_config_section_item(self, section: str, item: str):
             HTTP/400 if item is not found
             HTTP/404 if others error
             """
    -        config_dict = self.config.as_dict()
    +        config_dict = self.config.as_dict() if self.args.password else self.config.as_dict_secure()
             if section not in config_dict:
                 raise HTTPException(status.HTTP_400_BAD_REQUEST, f"Unknown configuration item {section}")
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.