GCVE-1-2026-20141 (CVE-2026-127046)

Vulnerability from gna-1 – Published: 2026-11-12 12:01 – Updated: 2026-11-12 13:49
VLAI
Title
MISP Modules Website Exposes External Tool API Keys in /external_tools/list Response
Summary
The MISP Modules website component contains an information disclosure vulnerability in the external tools management interface. The /external_tools/list endpoint returned stored API keys (the api_key field) in its JSON response via the ExternalTools model serializer. Additionally, the browser-based edit form pre-populated the API key input field with the stored credential value, exposing it in the DOM. The /external_tools/list endpoint is accessible without authentication (the regression tests verify the response for both authenticated and unauthenticated clients), meaning any network-reachable client could retrieve the API keys for all configured external tools. These keys are used by the server to authenticate submissions to external analysis or enrichment services, so their disclosure allows an attacker to impersonate the MISP instance or directly access those external services. The vulnerability also affected the edit workflow: the change_config endpoint previously required the API key to be present and non-empty on every save, forcing the key to round-trip through the client. The browser JavaScript stored the key in a reactive state object and updated the in-memory tool list with the credential value, further increasing the window of exposure in client-side memory and network traffic. Affected component: the website sub-application of MISP Modules, specifically the external_tools module (serializer in models.py, list endpoint, and the external_tools_index.html template). The impact is limited to confidentiality of the stored API keys; no integrity or availability impact on the MISP Modules website itself is indicated by the patch.
SSVC
Exploitation: none Automatable: yes Technical Impact: partial
Supplier · CNA (v2.0.3)
Decision recorded 2026-11-12 11:59 UTC
CWE
  • CWE-200 - Exposure of Sensitive Information to an Unauthorized Actor
  • CWE-522 - Insufficiently Protected Credentials
Assigner
CIRCL GNA GNA-1
GNA scorecard A 90/100 over 257 records in the last 180 days details
References
Impacted products
Vendor Product Version CPE status
misp misp-modules Affected: 0 , ≤ 3.1.4 (semver)
    cpe:2.3:a:misp:misp_modules:*:*:*:*:*:*:*:*
Create a notification for this product.
GCVE extensions
bcp-05-x-01
AI-assisted vulnerability information annotation
GCVE-BCP-05-X-01
Whole record AI-generated Not human-reviewed GNA-1

Draft vulnerability metadata was generated from a git-format patch using an Ollama-hosted language model. Human validation is required before publication.

ai-computer-assisted:llm-generatedai-computer-assisted:classification
Model Source Identifier
qwen3.8:27b ollama qwen3.8:27b
bcp-05-x-02
Patch-to-vulnerability generation provenance
GCVE-BCP-05-X-02
Generator
patch2vuln.py on 2026-11-12 11:59
Model
qwen3.8:27b
Input
https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch 200a89910bce…
Confidence
medium
Commit Subject Patch SHA-256
61c27893066c fix: [website] keep external tool API keys out of responses 200a89910bce…
Fix summary

The fix removes the api_key field from the ExternalTools.to_json() serializer so that /external_tools/list no longer returns credentials. The edit form is changed to a write-only pattern: the API key input starts empty, a blank or missing value on save retains the previously stored key, and a non-empty value replaces it. After a successful save the client clears the key field and does not propagate the credential into the in-memory tool list. Input validation is tightened to reject non-string or over-length key values. Server-side tool submissions continue to use the stored key from the database.

Patch summary

models.py: removed the api_key entry from ExternalTools.to_json(). external_tools.py (change_config endpoint): replaced the nested if-chain that required tool_api_key to be present and non-empty with a flat validation loop for tool_id/tool_name/tool_url, added a type-and-length check (string, max 60 chars) for tool_api_key when present, and made the field optional (write-only semantics). external_tools_core.py (change_config_core): changed tool.api_key assignment to be conditional on a truthy request_json.get('tool_api_key'). external_tools_index.html: initialized the form key field to empty string instead of tool.api_key, added placeholder and helper text, fixed a bug where the error-clearing selector referenced the wrong field, moved browser-state updates to after a successful HTTP response (res.ok check), and cleared the key input after save. README.md: documented the write-only key behavior. Tests: added browser-level (Playwright) and unit-level regression tests verifying the list endpoint omits api_key,空

CVSS rationale

AV:N: the /external_tools/list endpoint is reachable over the network via HTTP. AC:L: exploitation requires only a single GET request with no special conditions. AT:N: no attack prerequisites such as race conditions or specific timing. PR:N: regression tests confirm the endpoint returns 200 and previously included api_key for both authenticated and unauthenticated clients, indicating no privilege is required. UI:N: no victim interaction is needed; the attacker simply reads the response. VC:H: the exposed data is API keys (credentials) for external services, representing high confidentiality loss. VI:N and VA:N: no integrity or availability impact on the MISP Modules website. SC:H: the stolen API keys can be used to authenticate to external analysis/enrichment services, representing high confidentiality impact on a subsequent component. SI:N and SA:N: no integrity or availability impact on subsequent components is indicated.

Weakness rationale
  • CWE-200 The /external_tools/list endpoint returned stored API keys in its JSON response to any client (authenticated or not), exposing credentials to unauthorized parties. The browser form also pre-populated the key in the DOM.
  • CWE-522 API keys used to authenticate to external services were stored and transmitted without adequate protection: they appeared in API responses and in client-side form state, violating the principle that credentials should be write-only from the client perspective.
Attack pattern rationale
  • CAPEC-126 The closest available CAPEC pattern. The attack involves an attacker obtaining credential material (API keys) from a web application response and using it to authenticate to a subsequent service. CAPEC-126 covers the theft of session/credential tokens from a web application. The mapping is imperfect because the keys are long-lived API credentials rather than short-lived session tokens, and the attack does not involve a session per se, but the underlying mechanism (reading a credential from an HTTP response and replaying it) is the same class of attack. No CAPEC pattern specifically covers 'sensitive data in API response' without a session-hijacking framing, so this is the best available match.
Assumptions to verify
  • The /external_tools/list endpoint is accessible without authentication based on regression tests that verify the response for both authenticated and unauthenticated clients; however, the README notes that management operations require ADMIN_PASSWORD, so the list endpoint's access control may vary by deployment configuration.
  • CVSS SC:H assumes the exposed API keys grant meaningful access to external services; the actual scope of access depends on the specific external tools configured and is not specified in the patch.
  • No specific product version or release boundary is identified in the patch; the affected version range is therefore marked as unspecified.
  • CAPEC-126 is the closest available pattern but is not a perfect match; the vulnerability is more precisely an API response information disclosure than a session hijacking. No CAPEC pattern specifically covers 'sensitive credential in API JSON response' without a session framing.
  • The commit references issue #816 but no reporter or finder is named in the patch metadata or commit message.
  • The 60-character maximum length validation for API keys is a new constraint introduced by the patch; it is unclear whether keys longer than 60 characters were previously valid, which could affect deployments with longer keys.
Model comparison

Selected qwen3.8:27b by deterministic-consensus-v1
The selected result is closest to model consensus; this heuristic does not establish factual correctness and human review remains required.

Model Score Agreement Confidence Assumptions
qwen3.8:27b 6 11 medium 6
bcp-05-x-03
Vulnerability handling and disclosure timeline
GCVE-BCP-05-X-03
  1. 2026-11-12 08:37 UTC Fix developed Corrective change authored (61c27893066cee80d9711649765ebc2bccd0e4af): fix: [website] keep external tool API keys out of responses https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch
  2. 2026-11-12 11:58 UTC Fix available Patch retrieved from the supplied URL; retrieval time is used as the default availability time. https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch

{
  "containers": {
    "cna": {
      "affected": [
        {
          "cpes": [
            "cpe:2.3:a:misp:misp_modules:*:*:*:*:*:*:*:*"
          ],
          "modules": [
            "website/app/external_tools",
            "website/app/models"
          ],
          "product": "misp-modules",
          "programFiles": [
            "website/app/models/models.py",
            "website/app/external_tools/external_tools.py",
            "website/app/external_tools/external_tools_core.py",
            "website/app/templates/external_tools/external_tools_index.html"
          ],
          "repo": "https://github.com/MISP/misp-modules",
          "vendor": "misp",
          "versions": [
            {
              "lessThanOrEqual": "3.1.4",
              "status": "affected",
              "version": "0",
              "versionType": "semver"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:misp:misp-modules:*:*:*:*:*:*:*:*",
                  "versionEndIncluding": "3.1.4",
                  "versionStartIncluding": "0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Alexandre Dulaunoy"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "The MISP Modules website component contains an information disclosure vulnerability in the external tools management interface. The /external_tools/list endpoint returned stored API keys (the api_key field) in its JSON response via the ExternalTools model serializer. Additionally, the browser-based edit form pre-populated the API key input field with the stored credential value, exposing it in the DOM.\n\nThe /external_tools/list endpoint is accessible without authentication (the regression tests verify the response for both authenticated and unauthenticated clients), meaning any network-reachable client could retrieve the API keys for all configured external tools. These keys are used by the server to authenticate submissions to external analysis or enrichment services, so their disclosure allows an attacker to impersonate the MISP instance or directly access those external services.\n\nThe vulnerability also affected the edit workflow: the change_config endpoint previously required the API key to be present and non-empty on every save, forcing the key to round-trip through the client. The browser JavaScript stored the key in a reactive state object and updated the in-memory tool list with the credential value, further increasing the window of exposure in client-side memory and network traffic.\n\nAffected component: the website sub-application of MISP Modules, specifically the external_tools module (serializer in models.py, list endpoint, and the external_tools_index.html template). The impact is limited to confidentiality of the stored API keys; no integrity or availability impact on the MISP Modules website itself is indicated by the patch."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-126",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-126 Web Application Session Hijacking"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 9.2,
            "baseSeverity": "CRITICAL",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "HIGH",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "HIGH",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        },
        {
          "format": "SSVC",
          "other": {
            "content": {
              "options": [
                {
                  "Exploitation": "none"
                },
                {
                  "Automatable": "yes"
                },
                {
                  "Technical Impact": "partial"
                }
              ],
              "role": "Supplier",
              "timestamp": "2026-11-12T11:59:08Z",
              "version": "2.0.3"
            },
            "type": "SSVC"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-200",
              "description": "CWE-200 Exposure of Sensitive Information to an Unauthorized Actor",
              "lang": "en",
              "type": "CWE"
            }
          ]
        },
        {
          "descriptions": [
            {
              "cweId": "CWE-522",
              "description": "CWE-522 Insufficiently Protected Credentials",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "references": [
        {
          "name": "Security patch",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af"
        }
      ],
      "solutions": [
        {
          "lang": "en",
          "value": "The fix removes the api_key field from the ExternalTools.to_json() serializer so that /external_tools/list no longer returns credentials. The edit form is changed to a write-only pattern: the API key input starts empty, a blank or missing value on save retains the previously stored key, and a non-empty value replaces it. After a successful save the client clears the key field and does not propagate the credential into the in-memory tool list. Input validation is tightened to reject non-string or over-length key values. Server-side tool submissions continue to use the stored key from the database."
        }
      ],
      "title": "MISP Modules Website Exposes External Tool API Keys in /external_tools/list Response",
      "x_gcve": [
        {
          "extensions": {
            "bcp-05-x-01": {
              "ai_annotations": [
                {
                  "ai_level": "generated",
                  "description": "Draft vulnerability metadata was generated from a git-format patch using an Ollama-hosted language model. Human validation is required before publication.",
                  "gna_source": 1,
                  "models": [
                    {
                      "gna_source": 1,
                      "identifier": "qwen3.8:27b",
                      "name": "qwen3.8:27b",
                      "source": "ollama"
                    }
                  ],
                  "review_status": "none",
                  "scope": "record",
                  "tags": [
                    "ai-computer-assisted:llm-generated",
                    "ai-computer-assisted:classification"
                  ]
                }
              ]
            },
            "bcp-05-x-02": {
              "x_patch2vuln": {
                "assumptions": [
                  "The /external_tools/list endpoint is accessible without authentication based on regression tests that verify the response for both authenticated and unauthenticated clients; however, the README notes that management operations require ADMIN_PASSWORD, so the list endpoint\u0027s access control may vary by deployment configuration.",
                  "CVSS SC:H assumes the exposed API keys grant meaningful access to external services; the actual scope of access depends on the specific external tools configured and is not specified in the patch.",
                  "No specific product version or release boundary is identified in the patch; the affected version range is therefore marked as unspecified.",
                  "CAPEC-126 is the closest available pattern but is not a perfect match; the vulnerability is more precisely an API response information disclosure than a session hijacking. No CAPEC pattern specifically covers \u0027sensitive credential in API JSON response\u0027 without a session framing.",
                  "The commit references issue #816 but no reporter or finder is named in the patch metadata or commit message.",
                  "The 60-character maximum length validation for API keys is a new constraint introduced by the patch; it is unclear whether keys longer than 60 characters were previously valid, which could affect deployments with longer keys."
                ],
                "capecRationale": [
                  {
                    "capecId": "CAPEC-126",
                    "rationale": "The closest available CAPEC pattern. The attack involves an attacker obtaining credential material (API keys) from a web application response and using it to authenticate to a subsequent service. CAPEC-126 covers the theft of session/credential tokens from a web application. The mapping is imperfect because the keys are long-lived API credentials rather than short-lived session tokens, and the attack does not involve a session per se, but the underlying mechanism (reading a credential from an HTTP response and replaying it) is the same class of attack. No CAPEC pattern specifically covers \u0027sensitive data in API response\u0027 without a session-hijacking framing, so this is the best available match."
                  }
                ],
                "commit": "61c27893066cee80d9711649765ebc2bccd0e4af",
                "confidence": "medium",
                "credits": [
                  {
                    "lang": "en",
                    "type": "remediation developer",
                    "value": "Alexandre Dulaunoy"
                  }
                ],
                "cvssRationale": "AV:N: the /external_tools/list endpoint is reachable over the network via HTTP. AC:L: exploitation requires only a single GET request with no special conditions. AT:N: no attack prerequisites such as race conditions or specific timing. PR:N: regression tests confirm the endpoint returns 200 and previously included api_key for both authenticated and unauthenticated clients, indicating no privilege is required. UI:N: no victim interaction is needed; the attacker simply reads the response. VC:H: the exposed data is API keys (credentials) for external services, representing high confidentiality loss. VI:N and VA:N: no integrity or availability impact on the MISP Modules website. SC:H: the stolen API keys can be used to authenticate to external analysis/enrichment services, representing high confidentiality impact on a subsequent component. SI:N and SA:N: no integrity or availability impact on subsequent components is indicated.",
                "draft": false,
                "fixSummary": "The fix removes the api_key field from the ExternalTools.to_json() serializer so that /external_tools/list no longer returns credentials. The edit form is changed to a write-only pattern: the API key input starts empty, a blank or missing value on save retains the previously stored key, and a non-empty value replaces it. After a successful save the client clears the key field and does not propagate the credential into the in-memory tool list. Input validation is tightened to reject non-string or over-length key values. Server-side tool submissions continue to use the stored key from the database.",
                "generatedAt": "2026-11-12T11:59:08.631868Z",
                "generator": "patch2vuln.py",
                "model": "qwen3.8:27b",
                "modelComparison": {
                  "potentialErrors": [],
                  "rankings": [
                    {
                      "agreementScore": 11,
                      "assumptionCount": 6,
                      "confidence": "medium",
                      "model": "qwen3.8:27b",
                      "score": 6
                    }
                  ],
                  "selectedModel": "qwen3.8:27b",
                  "selectionMethod": "deterministic-consensus-v1",
                  "selectionNotice": "The selected result is closest to model consensus; this heuristic does not establish factual correctness and human review remains required."
                },
                "patchSha256": "200a89910bce4823c08ee129545edc9fe7177cb0de9c5555925aa075155ca61b",
                "patchSummary": "models.py: removed the api_key entry from ExternalTools.to_json(). external_tools.py (change_config endpoint): replaced the nested if-chain that required tool_api_key to be present and non-empty with a flat validation loop for tool_id/tool_name/tool_url, added a type-and-length check (string, max 60 chars) for tool_api_key when present, and made the field optional (write-only semantics). external_tools_core.py (change_config_core): changed tool.api_key assignment to be conditional on a truthy request_json.get(\u0027tool_api_key\u0027). external_tools_index.html: initialized the form key field to empty string instead of tool.api_key, added placeholder and helper text, fixed a bug where the error-clearing selector referenced the wrong field, moved browser-state updates to after a successful HTTP response (res.ok check), and cleared the key input after save. README.md: documented the write-only key behavior. Tests: added browser-level (Playwright) and unit-level regression tests verifying the list endpoint omits api_key,\u7a7a",
                "patchTruncated": false,
                "patches": [
                  {
                    "commit": "61c27893066cee80d9711649765ebc2bccd0e4af",
                    "date": "Thu, 12 Nov 2026 09:37:45 +0100",
                    "patchSha256": "200a89910bce4823c08ee129545edc9fe7177cb0de9c5555925aa075155ca61b",
                    "retrievedAt": "2026-11-12T11:58:13.406720Z",
                    "source": "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch",
                    "sourceUrl": "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch",
                    "subject": "fix: [website] keep external tool API keys out of responses"
                  }
                ],
                "source": "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch",
                "ssvc": {
                  "options": [
                    {
                      "Exploitation": "none"
                    },
                    {
                      "Automatable": "yes"
                    },
                    {
                      "Technical Impact": "partial"
                    }
                  ],
                  "role": "Supplier",
                  "timestamp": "2026-11-12T11:59:08Z",
                  "version": "2.0.3"
                },
                "subject": "fix: [website] keep external tool API keys out of responses",
                "weaknessRationale": [
                  {
                    "cweId": "CWE-200",
                    "rationale": "The /external_tools/list endpoint returned stored API keys in its JSON response to any client (authenticated or not), exposing credentials to unauthorized parties. The browser form also pre-populated the key in the DOM."
                  },
                  {
                    "cweId": "CWE-522",
                    "rationale": "API keys used to authenticate to external services were stored and transmitted without adequate protection: they appeared in API responses and in client-side form state, violating the principle that credentials should be write-only from the client perspective."
                  }
                ]
              }
            },
            "bcp-05-x-03": {
              "x_timeline": {
                "events": [
                  {
                    "description": "Corrective change authored (61c27893066cee80d9711649765ebc2bccd0e4af): fix: [website] keep external tool API keys out of responses",
                    "id": "evt-fix-developed-1",
                    "references": [
                      "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch"
                    ],
                    "timestamp": "2026-11-12T08:37:45Z",
                    "type": "fix-developed"
                  },
                  {
                    "description": "Patch retrieved from the supplied URL; retrieval time is used as the default availability time.",
                    "id": "evt-fix-available-1",
                    "references": [
                      "https://github.com/MISP/misp-modules/commit/61c27893066cee80d9711649765ebc2bccd0e4af.patch"
                    ],
                    "timestamp": "2026-11-12T11:58:13.406720Z",
                    "type": "fix-available"
                  }
                ]
              }
            }
          },
          "recordType": "advisory",
          "vulnId": "gcve-1-2026-20141"
        }
      ]
    }
  },
  "cveMetadata": {
    "cveId": "CVE-2026-127046",
    "datePublished": "2026-11-12T12:01:50.481806Z",
    "dateReserved": "2026-11-12T12:04:58.364Z",
    "dateUpdated": "2026-11-12T13:49:40.957416Z",
    "state": "PUBLISHED",
    "vulnId": "gcve-1-2026-20141"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2.0"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
How durations are calculated

Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.

Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.

Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.