300 lines
19 KiB
JSON
300 lines
19 KiB
JSON
{
|
||
"dataType": "CVE_RECORD",
|
||
"dataVersion": "5.2",
|
||
"cveMetadata": {
|
||
"cveId": "CVE-2026-95701",
|
||
"assignerOrgId": "5a6e4751-2f3f-4070-9419-94fb35b644e8",
|
||
"state": "PUBLISHED",
|
||
"assignerShortName": "CIRCL",
|
||
"dateReserved": "2026-09-22T14:44:19.514Z",
|
||
"datePublished": "2026-09-22T14:44:21.916Z",
|
||
"dateUpdated": "2026-09-22T14:59:46.097Z"
|
||
},
|
||
"containers": {
|
||
"cna": {
|
||
"affected": [
|
||
{
|
||
"modules": [
|
||
"UsersController::__statisticsOrgs"
|
||
],
|
||
"product": "MISP",
|
||
"programFiles": [
|
||
"app/Controller/UsersController.php"
|
||
],
|
||
"repo": "https://github.com/MISP/MISP",
|
||
"vendor": "MISP",
|
||
"versions": [
|
||
{
|
||
"lessThan": "2.5.47",
|
||
"status": "affected",
|
||
"version": "0",
|
||
"versionType": "semver"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"credits": [
|
||
{
|
||
"lang": "en",
|
||
"type": "reporter",
|
||
"value": "Jeroen Pinoy"
|
||
},
|
||
{
|
||
"lang": "en",
|
||
"type": "remediation developer",
|
||
"value": "iglocska"
|
||
},
|
||
{
|
||
"lang": "en",
|
||
"type": "remediation developer",
|
||
"value": "Claude Opus 4.8"
|
||
}
|
||
],
|
||
"descriptions": [
|
||
{
|
||
"lang": "en",
|
||
"supportingMedia": [
|
||
{
|
||
"base64": false,
|
||
"type": "text/html",
|
||
"value": "<p>In MISP, the __statisticsOrgs method in UsersController.php used the organization name directly as a file-system path component when checking for the existence of an organization logo image. The original code called file_exists() with a path constructed as APP . 'webroot' . DS . 'img' . DS . 'orgs' . DS . $k . '.png', where $k is the organization name. Because the referenced directory (app/webroot/img/orgs) no longer exists in current MISP deployments (org logos were relocated to files/img/orgs), the check was functionally dead and never triggered. However, the underlying pattern—concatenating an attacker-influenced organization name into a file path without sanitization—constitutes a path traversal weakness. An organization name containing directory traversal sequences (e.g., '../../../../etc/passwd') would, if the target directory existed, allow an authenticated user with the ability to create or rename an organization to probe for the existence of arbitrary files on the server.</p>"
|
||
}
|
||
],
|
||
"value": "In MISP, the __statisticsOrgs method in UsersController.php used the organization name directly as a file-system path component when checking for the existence of an organization logo image. The original code called file_exists() with a path constructed as APP . 'webroot' . DS . 'img' . DS . 'orgs' . DS . $k . '.png', where $k is the organization name. Because the referenced directory (app/webroot/img/orgs) no longer exists in current MISP deployments (org logos were relocated to files/img/orgs), the check was functionally dead and never triggered. However, the underlying pattern—concatenating an attacker-influenced organization name into a file path without sanitization—constitutes a path traversal weakness. An organization name containing directory traversal sequences (e.g., '../../../../etc/passwd') would, if the target directory existed, allow an authenticated user with the ability to create or rename an organization to probe for the existence of arbitrary files on the server."
|
||
}
|
||
],
|
||
"impacts": [
|
||
{
|
||
"capecId": "CAPEC-1",
|
||
"descriptions": [
|
||
{
|
||
"lang": "en",
|
||
"value": "CAPEC-1 String Manipulation"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"metrics": [
|
||
{
|
||
"cvssV4_0": {
|
||
"Automatable": "NOT_DEFINED",
|
||
"Recovery": "NOT_DEFINED",
|
||
"Safety": "NOT_DEFINED",
|
||
"attackComplexity": "LOW",
|
||
"attackRequirements": "NONE",
|
||
"attackVector": "NETWORK",
|
||
"baseScore": 5.1,
|
||
"baseSeverity": "MEDIUM",
|
||
"privilegesRequired": "HIGH",
|
||
"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:H/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-22",
|
||
"description": "CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')",
|
||
"lang": "en",
|
||
"type": "CWE"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"providerMetadata": {
|
||
"orgId": "5a6e4751-2f3f-4070-9419-94fb35b644e8",
|
||
"shortName": "CIRCL",
|
||
"dateUpdated": "2026-09-22T14:44:21.916Z"
|
||
},
|
||
"references": [
|
||
{
|
||
"name": "Security patch",
|
||
"tags": [
|
||
"patch"
|
||
],
|
||
"url": "https://github.com/MISP/MISP/commit/a2f7cba6e"
|
||
}
|
||
],
|
||
"solutions": [
|
||
{
|
||
"lang": "en",
|
||
"supportingMedia": [
|
||
{
|
||
"base64": false,
|
||
"type": "text/html",
|
||
"value": "<p>The fix corrects the logo directory path from the obsolete app/webroot/img/orgs to the current files/img/orgs location, expands the lookup to cover id, name, and uuid fields across png and svg extensions (mirroring the getOrgLogo helper), and adds a security guard: the candidate path is resolved with realpath() and verified via str_starts_with() against the resolved base directory, so any organization name containing traversal sequences (../) that would resolve outside files/img/orgs is rejected.</p>"
|
||
}
|
||
],
|
||
"value": "The fix corrects the logo directory path from the obsolete app/webroot/img/orgs to the current files/img/orgs location, expands the lookup to cover id, name, and uuid fields across png and svg extensions (mirroring the getOrgLogo helper), and adds a security guard: the candidate path is resolved with realpath() and verified via str_starts_with() against the resolved base directory, so any organization name containing traversal sequences (../) that would resolve outside files/img/orgs is rejected."
|
||
}
|
||
],
|
||
"title": "MISP Path Traversal via Organization Name in Org-Statistics Logo Check",
|
||
"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": "full",
|
||
"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.47, 50 commits after fix); the exact fixed release tag is not stated in the patch metadata, so 'less_than 2.5.47' is an approximation and may need CNA confirmation.",
|
||
"The vulnerability was latent in deployed instances because the referenced directory (app/webroot/img/orgs) did not exist; the CVSS reflects the code-level weakness rather than a confirmed active exploit.",
|
||
"PR:H assumes that creating or renaming an organization requires elevated privileges (admin or org-admin); if MISP allows lower-privileged users to set org names, PR could be lower.",
|
||
"CAPEC-1 (String Manipulation) is the closest available pattern; the exact CAPEC for path traversal via a stored string field is not explicitly enumerated in the CAPEC catalog, so this is a best-effort mapping.",
|
||
"The Co-Authored-By line references an AI assistant (Claude Opus 4.8); it is credited as a tool rather than a human remediation developer."
|
||
],
|
||
"capecRationale": [
|
||
{
|
||
"capecId": "CAPEC-1",
|
||
"rationale": "The attack pattern involves manipulating a string value (the organization name) to inject path traversal sequences (../) that cause the application to reference files outside the intended directory. CAPEC-1 is the closest match because the core technique is crafting a string input to alter the application's file-path resolution. Uncertainty: CAPEC-126 (Leveraging Unintended Functionality) could also apply since the logo-existence check was an unintended side channel, but CAPEC-1 more directly describes the string-manipulation mechanism."
|
||
}
|
||
],
|
||
"commit": "a2f7cba6e74b791e30013f10720dadbc4117d989",
|
||
"confidence": "medium",
|
||
"credits": [
|
||
{
|
||
"lang": "en",
|
||
"type": "reporter",
|
||
"value": "Jeroen Pinoy"
|
||
},
|
||
{
|
||
"lang": "en",
|
||
"type": "remediation developer",
|
||
"value": "iglocska"
|
||
},
|
||
{
|
||
"lang": "en",
|
||
"type": "remediation developer",
|
||
"value": "Claude Opus 4.8"
|
||
}
|
||
],
|
||
"cvssRationale": "AV:N – MISP is a network-accessible web application. AC:L – the traversal sequence in an org name is straightforward to construct. AT:N – no special target-side conditions beyond the org name being stored. PR:H – the attacker must have sufficient privileges to create or rename an organization (typically admin or org-admin role). UI:N – no user interaction required; the check fires server-side during statistics rendering. VC:L – the impact is limited to file-existence disclosure (boolean oracle); file contents are not read. VI:N, VA:N – no integrity or availability impact. SC/SI/SA:N – no secondary-system impact. Note: the vulnerability was latent in practice because the referenced directory did not exist, but the code pattern was exploitable if the directory were present or restored.",
|
||
"fixSummary": "The fix corrects the logo directory path from the obsolete app/webroot/img/orgs to the current files/img/orgs location, expands the lookup to cover id, name, and uuid fields across png and svg extensions (mirroring the getOrgLogo helper), and adds a security guard: the candidate path is resolved with realpath() and verified via str_starts_with() against the resolved base directory, so any organization name containing traversal sequences (../) that would resolve outside files/img/orgs is rejected.",
|
||
"generatedAt": "2026-09-22T14:38:57.879793Z",
|
||
"generator": "patch2vuln.py",
|
||
"model": "qwen3.8:27b",
|
||
"modelComparison": {
|
||
"rankings": [
|
||
{
|
||
"agreementScore": 9,
|
||
"assumptionCount": 5,
|
||
"confidence": "medium",
|
||
"model": "qwen3.8:27b",
|
||
"score": 5
|
||
}
|
||
],
|
||
"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": "79f69959d0bcac7da9eea5e1dcd7edc108868ea8382a8e477d3c72e749f06a37",
|
||
"patchSummary": "In app/Controller/UsersController.php __statisticsOrgs(): (1) added 'uuid' to the Organisation query fields; (2) replaced the single file_exists() call against APP/webroot/img/orgs/$k.png with a nested loop over fields [id, name, uuid] and extensions [png, svg]; (3) for each candidate, called realpath() on the full path and compared it with str_starts_with() against the realpath of the base directory (APP/files/img/orgs/), setting the logo flag only when the resolved path is confirmed to be inside that directory; (4) added a break 2 to exit both loops once a match is found.",
|
||
"patchTruncated": false,
|
||
"patches": [
|
||
{
|
||
"commit": "a2f7cba6e74b791e30013f10720dadbc4117d989",
|
||
"patchSha256": "79f69959d0bcac7da9eea5e1dcd7edc108868ea8382a8e477d3c72e749f06a37",
|
||
"source": "https://github.com/MISP/MISP/commit/a2f7cba6e.patch",
|
||
"sourceUrl": "https://github.com/MISP/MISP/commit/a2f7cba6e.patch",
|
||
"subject": "fix: [ui] Point the org-statistics logo flag at the live"
|
||
}
|
||
],
|
||
"source": "https://github.com/MISP/MISP/commit/a2f7cba6e.patch",
|
||
"subject": "fix: [ui] Point the org-statistics logo flag at the live",
|
||
"tagVersionBoundary": {
|
||
"commits_after_fix": 50,
|
||
"repository": "https://github.com/MISP/MISP",
|
||
"tag": "v2.5.47",
|
||
"version": "2.5.47",
|
||
"version_type": "semver"
|
||
},
|
||
"weaknessRationale": [
|
||
{
|
||
"cweId": "CWE-22",
|
||
"rationale": "The organization name (an attacker-influenced string) was concatenated directly into a file-system path for a file_exists() check without any sanitization or directory-confinement validation. The fix explicitly guards against '../' sequences escaping the intended directory, confirming the weakness is path traversal."
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"recordType": "advisory",
|
||
"vulnId": "GCVE-1-2026-20065"
|
||
}
|
||
]
|
||
},
|
||
"adp": [
|
||
{
|
||
"metrics": [
|
||
{
|
||
"other": {
|
||
"type": "ssvc",
|
||
"content": {
|
||
"timestamp": "2026-09-22T14:59:24.647249Z",
|
||
"id": "CVE-2026-95701",
|
||
"options": [
|
||
{
|
||
"Exploitation": "none"
|
||
},
|
||
{
|
||
"Automatable": "no"
|
||
},
|
||
{
|
||
"Technical Impact": "partial"
|
||
}
|
||
],
|
||
"role": "CISA Coordinator",
|
||
"version": "2.0.3"
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"title": "CISA ADP Vulnrichment",
|
||
"providerMetadata": {
|
||
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
|
||
"shortName": "CISA-ADP",
|
||
"dateUpdated": "2026-09-22T14:59:46.097Z"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
} |