GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GCVE-1-2026-20010 (CVE-2026-91851)

Vulnerability from gna-1 – Published: 2026-09-15 08:49 – Updated: 2026-09-15 08:49
VLAI
Title
MISP Dashboard Template ACL Bypass Due to VARCHAR-to-Integer Type Coercion in Permission Flag Comparison
Summary
Affected versions of MISP incorrectly filter dashboard templates that are restricted to a specific permission flag. DashboardsController::listTemplates() allowed a template when either:  - its restrict_to_permission_flag matched one of the current user’s permission flags, or  - restrict_to_permission_flag equaled integer 0 However, restrict_to_permission_flag is a varchar. MySQL therefore performed numeric coercion when comparing the column against integer 0. Strings such as perm_site_admin convert numerically to zero, making expressions such as perm_site_admin = 0 evaluate true and causing the “unrestricted” branch to match permission-restricted templates as well. Version affected: ≤2.5.45
CWE
Assigner
GNA-1 This instance
References
Impacted products
Vendor Product Version CPE status
MISP MISP Affected: 0 , < 2.5.46 (semver)
guessed Create a notification for this product.
GCVE extensions
AI involvement GCVE-BCP-05-X-01
Whole record AI-generated Review: review 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
Patch provenance GCVE-BCP-05-X-02
Generator
patch2vuln.py on 2026-09-15 08:40
Model
qwen3.8:27b
Input
https://github.com/MISP/MISP/commit/245b8d63a.patch ac03cd1103d5…
Confidence
medium
Commit Subject Patch SHA-256
245b8d63a379 fix: [acl] Compare the dashboard template permission flag as ac03cd1103d5…
Fix summary

The fix corrects the type mismatch in the permission flag comparison by replacing the integer literal 0 with the explicit string values '' and '0', which are the actual database values representing an unrestricted dashboard template. This ensures MySQL performs a proper string-to-string comparison, so only rows genuinely marked as unrestricted are returned, restoring the intended per-permission-level access control on dashboard templates.

Patch summary

In app/Controller/DashboardsController.php, the listTemplates() method's query condition was changed from ['Dashboard.restrict_to_permission_flag' => 0] to ['Dashboard.restrict_to_permission_flag' => ['', '0']]. A multi-line comment was added explaining that restrict_to_permission_flag is a VARCHAR column and that comparing it to integer 0 causes MySQL to coerce the column, making the clause a no-op. The two values that actually represent unrestricted access are the empty string (column default) and the string '0' (posted by the save form).

CVSS rationale

The vulnerability is exploitable over the network (AV:N) via the MISP web interface with low attack complexity (AC:L) and no attack target manipulation (AT:N). It requires a low-privilege authenticated user (PR:L) and no user interaction (UI:N). The impact is limited to confidentiality (VC:L) as restricted dashboard template definitions are disclosed to unauthorized users; there is no integrity or availability impact (VI:N, VA:N) and no secondary effects (SC:N, SI:N, SA:N). The severity is moderate because the disclosed data is dashboard template metadata rather than raw threat intelligence, but it still represents a breach of the intended access control boundary.

Weakness rationale
  • CWE-863 The permission-based filter on dashboard templates was effectively bypassed because the type-coerced comparison matched all rows, allowing any authenticated user to access templates restricted to higher-privilege roles. The authorization check was present in code but did not function correctly.
  • CWE-697 The root cause is a comparison between a VARCHAR column and an integer literal. MySQL's implicit type coercion caused the comparison to evaluate to TRUE for all non-numeric string values, making the intended filter a no-op. This is a classic incorrect comparison due to type mismatch.
Assumptions to verify
  • The affected version range is inferred from the tag_version_boundary (v2.5.46 with 200 commits after fix); no explicit affected or fixed version is stated in the patch metadata.
  • The vulnerability requires an authenticated MISP user with any role; the exact minimum privilege level needed to access the listTemplates endpoint is not specified in the patch.
  • The impact is assessed as Low confidentiality because the disclosed data is dashboard template definitions (layout, widget configuration) rather than raw threat intelligence or user credentials.
  • The MySQL type-coercion behavior described in the commit message and code comments is assumed to be accurate for the MySQL versions supported by MISP.
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 9 medium 4

{
  "containers": {
    "cna": {
      "affected": [
        {
          "modules": [
            "DashboardsController"
          ],
          "product": "MISP",
          "programFiles": [
            "app/Controller/DashboardsController.php"
          ],
          "repo": "https://github.com/MISP/MISP",
          "vendor": "MISP",
          "versions": [
            {
              "lessThan": "2.5.46",
              "status": "affected",
              "version": "0",
              "versionType": "semver"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "iglocska"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Claude Opus 5 (1M context)"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003e\u003c/p\u003e\u003cp\u003eAffected versions of MISP incorrectly filter dashboard templates that are restricted to a specific permission flag.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eDashboardsController::listTemplates()\u003c/code\u003e allowed a template when either:\u003c/p\u003e\u003cp\u003e\u003c/p\u003e\u003cdiv\u003e\u2003-\u0026nbsp;its \u003ccode\u003erestrict_to_permission_flag\u003c/code\u003e matched one of the current user\u2019s permission flags, or\u003c/div\u003e\u003cdiv\u003e\u2003-\u0026nbsp;\u003ccode\u003erestrict_to_permission_flag\u003c/code\u003e equaled integer \u003ccode\u003e0\u003c/code\u003e\u003c/div\u003e\u003cdiv\u003e\u003cbr\u003e\u003ccode\u003e\u003c/code\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003e\u003c/code\u003e\u003c/p\u003e\u003cp\u003eHowever, \u003ccode\u003erestrict_to_permission_flag\u003c/code\u003e is a \u003ccode\u003evarchar\u003c/code\u003e. MySQL therefore performed numeric coercion when comparing the column against integer \u003ccode\u003e0\u003c/code\u003e. Strings such as \u003ccode\u003eperm_site_admin\u003c/code\u003e convert numerically to zero, making expressions such as \u003ccode\u003eperm_site_admin = 0\u003c/code\u003e evaluate true and causing the \u201cunrestricted\u201d branch to match permission-restricted templates as well.\u003c/p\u003e\u003cp\u003e\u003c/p\u003e\u003cp\u003eVersion affected: \u22642.5.45\u003cbr\u003e\u003c/p\u003e"
            }
          ],
          "value": "Affected versions of MISP incorrectly filter dashboard templates that are restricted to a specific permission flag.\n\n\nDashboardsController::listTemplates() allowed a template when either:\n\n\n\n\u2003-\u00a0its restrict_to_permission_flag matched one of the current user\u2019s permission flags, or\n\n\u2003-\u00a0restrict_to_permission_flag equaled integer 0\n\n\n\n\n\n\nHowever, restrict_to_permission_flag is a varchar. MySQL therefore performed numeric coercion when comparing the column against integer 0. Strings such as perm_site_admin convert numerically to zero, making expressions such as perm_site_admin = 0 evaluate true and causing the \u201cunrestricted\u201d branch to match permission-restricted templates as well.\n\n\n\nVersion affected: \u22642.5.45"
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-1",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 5.3,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "LOW",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "LOW",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-863",
              "description": "CWE-863 Incorrect Authorization",
              "lang": "en",
              "type": "CWE"
            }
          ]
        },
        {
          "descriptions": [
            {
              "cweId": "CWE-697",
              "description": "CWE-697 Incorrect Comparison",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "orgId": "00000000-0000-4000-9000-000000000000"
      },
      "references": [
        {
          "name": "Security patch",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/MISP/MISP/commit/245b8d63a"
        }
      ],
      "solutions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThe fix corrects the type mismatch in the permission flag comparison by replacing the integer literal 0 with the explicit string values \u0027\u0027 and \u00270\u0027, which are the actual database values representing an unrestricted dashboard template. This ensures MySQL performs a proper string-to-string comparison, so only rows genuinely marked as unrestricted are returned, restoring the intended per-permission-level access control on dashboard templates.\u003c/p\u003e"
            }
          ],
          "value": "The fix corrects the type mismatch in the permission flag comparison by replacing the integer literal 0 with the explicit string values \u0027\u0027 and \u00270\u0027, which are the actual database values representing an unrestricted dashboard template. This ensures MySQL performs a proper string-to-string comparison, so only rows genuinely marked as unrestricted are returned, restoring the intended per-permission-level access control on dashboard templates."
        }
      ],
      "title": "MISP Dashboard Template ACL Bypass Due to VARCHAR-to-Integer Type Coercion in Permission Flag Comparison",
      "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": "review",
                  "scope": "record",
                  "tags": [
                    "ai-computer-assisted:llm-generated",
                    "ai-computer-assisted:classification"
                  ]
                }
              ]
            },
            "bcp-05-x-02": {
              "x_patch2vuln": {
                "assumptions": [
                  "The affected version range is inferred from the tag_version_boundary (v2.5.46 with 200 commits after fix); no explicit affected or fixed version is stated in the patch metadata.",
                  "The vulnerability requires an authenticated MISP user with any role; the exact minimum privilege level needed to access the listTemplates endpoint is not specified in the patch.",
                  "The impact is assessed as Low confidentiality because the disclosed data is dashboard template definitions (layout, widget configuration) rather than raw threat intelligence or user credentials.",
                  "The MySQL type-coercion behavior described in the commit message and code comments is assumed to be accurate for the MySQL versions supported by MISP."
                ],
                "commit": "245b8d63a3794d048fb88275512fa0d32981f0b8",
                "confidence": "medium",
                "credits": [
                  {
                    "lang": "en",
                    "type": "remediation developer",
                    "value": "iglocska"
                  },
                  {
                    "lang": "en",
                    "type": "remediation developer",
                    "value": "Claude Opus 5 (1M context)"
                  }
                ],
                "cvssRationale": "The vulnerability is exploitable over the network (AV:N) via the MISP web interface with low attack complexity (AC:L) and no attack target manipulation (AT:N). It requires a low-privilege authenticated user (PR:L) and no user interaction (UI:N). The impact is limited to confidentiality (VC:L) as restricted dashboard template definitions are disclosed to unauthorized users; there is no integrity or availability impact (VI:N, VA:N) and no secondary effects (SC:N, SI:N, SA:N). The severity is moderate because the disclosed data is dashboard template metadata rather than raw threat intelligence, but it still represents a breach of the intended access control boundary.",
                "draft": false,
                "fixSummary": "The fix corrects the type mismatch in the permission flag comparison by replacing the integer literal 0 with the explicit string values \u0027\u0027 and \u00270\u0027, which are the actual database values representing an unrestricted dashboard template. This ensures MySQL performs a proper string-to-string comparison, so only rows genuinely marked as unrestricted are returned, restoring the intended per-permission-level access control on dashboard templates.",
                "generatedAt": "2026-09-15T08:40:44.690048Z",
                "generator": "patch2vuln.py",
                "model": "qwen3.8:27b",
                "modelComparison": {
                  "rankings": [
                    {
                      "agreementScore": 9,
                      "assumptionCount": 4,
                      "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": "ac03cd1103d5fb0998c2406836df41d3449e5a5d6a0a5d2ffc77685eba48e188",
                "patchSummary": "In app/Controller/DashboardsController.php, the listTemplates() method\u0027s query condition was changed from [\u0027Dashboard.restrict_to_permission_flag\u0027 =\u003e 0] to [\u0027Dashboard.restrict_to_permission_flag\u0027 =\u003e [\u0027\u0027, \u00270\u0027]]. A multi-line comment was added explaining that restrict_to_permission_flag is a VARCHAR column and that comparing it to integer 0 causes MySQL to coerce the column, making the clause a no-op. The two values that actually represent unrestricted access are the empty string (column default) and the string \u00270\u0027 (posted by the save form).",
                "patchTruncated": false,
                "patches": [
                  {
                    "commit": "245b8d63a3794d048fb88275512fa0d32981f0b8",
                    "patchSha256": "ac03cd1103d5fb0998c2406836df41d3449e5a5d6a0a5d2ffc77685eba48e188",
                    "source": "https://github.com/MISP/MISP/commit/245b8d63a.patch",
                    "sourceUrl": "https://github.com/MISP/MISP/commit/245b8d63a.patch",
                    "subject": "fix: [acl] Compare the dashboard template permission flag as"
                  }
                ],
                "source": "https://github.com/MISP/MISP/commit/245b8d63a.patch",
                "subject": "fix: [acl] Compare the dashboard template permission flag as",
                "tagVersionBoundary": {
                  "commits_after_fix": 200,
                  "repository": "https://github.com/MISP/MISP",
                  "tag": "v2.5.46",
                  "version": "2.5.46",
                  "version_type": "semver"
                },
                "weaknessRationale": [
                  {
                    "cweId": "CWE-863",
                    "rationale": "The permission-based filter on dashboard templates was effectively bypassed because the type-coerced comparison matched all rows, allowing any authenticated user to access templates restricted to higher-privilege roles. The authorization check was present in code but did not function correctly."
                  },
                  {
                    "cweId": "CWE-697",
                    "rationale": "The root cause is a comparison between a VARCHAR column and an integer literal. MySQL\u0027s implicit type coercion caused the comparison to evaluate to TRUE for all non-numeric string values, making the intended filter a no-op. This is a classic incorrect comparison due to type mismatch."
                  }
                ]
              }
            }
          },
          "recordType": "advisory",
          "vulnId": "GCVE-1-2026-20010"
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "00000000-0000-4000-9000-000000000000",
    "cveId": "CVE-2026-91851",
    "datePublished": "2026-09-15T08:49:54.480630Z",
    "dateReserved": "2026-09-15T08:49:59.734Z",
    "dateUpdated": "2026-09-15T08:49:59.806159Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1-2026-20010"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.1"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…