VYPR
Medium severityNVD Advisory· Published Jun 12, 2026

CVE-2026-54394

CVE-2026-54394

Description

MISP path traversal in OrganisationsController::getOrgLogo allows reading arbitrary .png/.svg files via org-controlled fields; fixed by realpath() validation.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

MISP path traversal in OrganisationsController::getOrgLogo allows reading arbitrary .png/.svg files via org-controlled fields; fixed by realpath() validation.

Vulnerability

MISP version 2.4.167 and earlier contain a path traversal vulnerability in OrganisationsController::getOrgLogo. The vulnerable code builds organisation logo file paths using organisation-controlled fields (id, name, uuid) without ensuring the resolved file remains inside the intended directory APP/files/img/orgs/. This allows an attacker who can influence an organisation field (e.g., the organisation name) to traverse directories and retrieve arbitrary readable .png or .svg files from outside the logo directory.

Exploitation

An attacker needs to be able to set or modify an organisation field such as the organisation name. By including path traversal sequences (e.g., ../../../../etc/passwd but limited to .png and .svg extensions) in the field value, the attacker can craft a request to OrganisationsController::getOrgLogo that causes MISP to serve an arbitrary file with a matching extension. No authentication beyond organisation-level write access is required, though the attacker must have permission to modify organisation details.

Impact

Successful exploitation allows an attacker to read arbitrary .png or .svg files on the server, including sensitive configuration files or user data that happen to have those extensions. This leads to information disclosure. The read files are returned to the attacker in the HTTP response.

Mitigation

The vulnerability is fixed in commit b865deb [1]. The fix uses realpath() to resolve the candidate file path and checks that it starts with the real base directory path before serving the file. Users should update to the latest version of MISP containing this commit. No workaround is currently available; organisations should apply the patch as soon as possible.

AI Insight generated on Jun 12, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2
  • Misp/Mispreferences2 versions
    (expand)+ 1 more
    • (no CPE)
    • (no CPE)

Patches

1
b865deb036ca

fix: [security] org logo path traversal and xss in ui_beta

https://github.com/MISP/MISPiglocskaJun 11, 2026via nvd-ref
2 files changed · +15 13
  • app/Controller/OrganisationsController.php+10 12 modified
    @@ -411,22 +411,20 @@ public function getOrgLogo($id) {
                 throw new NotFoundException(__('Invalid organisation'));
             }
             $path = APP . 'files/img/orgs/';
    -        $image = null;
    +        $realBase = realpath($path);
             foreach (['id', 'name', 'uuid'] as $field) {
    -            foreach (['png', 'svg'] as $extensions) {
    -                if (file_exists($path . $org['Organisation'][$field] . '.' . $extensions)) {
    -                    $this->response->file($path . $org['Organisation'][$field] . '.' . $extensions, ['download' => false, 'name' => $org['Organisation']['id'] . '.' . $extensions]);
    +            foreach (['png', 'svg'] as $extension) {
    +                $candidate = realpath($path . $org['Organisation'][$field] . '.' . $extension);
    +                // realpath() resolves '..' and symlinks and returns false when the file does not
    +                // exist; the prefix check rejects anything that escapes the orgs directory. Without
    +                // it an attacker-controlled field such as the organisation name (e.g.
    +                // '../../../../AI-marketing') would allow path traversal to arbitrary png/svg files.
    +                if ($candidate !== false && $realBase !== false && str_starts_with($candidate, $realBase . DS)) {
    +                    $this->response->file($candidate, ['download' => false, 'name' => $org['Organisation']['id'] . '.' . $extension]);
                         return $this->response;
                     }
                 }
             }
    -        if ($image) {
    -            $filePath = $path . $image;
    -            $this->response->file($filePath, array('download' => false, 'name' => $image));
    -            return $this->response;
    -        } else {
    -            throw new NotFoundException(__('Organisation logo not found'));
    -        }
    -
    +        throw new NotFoundException(__('Organisation logo not found'));
         }
     }
    
  • app/View/Themed/UiBeta/Events/index.ctp+5 1 modified
    @@ -120,7 +120,11 @@
                     </select>
                     <input type="text" id="quickFilterField" class="form-control beta-search-input" placeholder="<?= __('Enter value to search') ?>" data-searchkey="<?= h($searchKey) ?>">
                     <button id="quickFilterButton" class="btn btn-primary beta-search-button"><?= __('Filter') ?></button>
    -                <button class="btn btn-default beta-advanced-filter-button" onclick="getPopup('<?= h($urlparams) ?>', 'events', 'filterEventIndex')">
    +                <?php /* json_encode emits a properly-escaped JS string literal; h() then guards the
    +                       attribute layer. Plain h($urlparams) inside a single-quoted JS string is unsafe
    +                       here: the browser HTML-decodes the onclick value before JS parsing, restoring any
    +                       &#039; and allowing a crafted searcheventinfo value to break out (XSS). */ ?>
    +                <button class="btn btn-default beta-advanced-filter-button" onclick="getPopup(<?= h(json_encode($urlparams)) ?>, 'events', 'filterEventIndex')">
                         <i class="fa fa-search"></i> <?= __('Advanced Filter...') ?>
                     </button>
                     <button id="multi-delete-button" class="btn btn-default hidden mass-delete" onclick="multiSelectDeleteEvents()" title="<?= __('Delete selected events') ?>">
    

Vulnerability mechanics

Root cause

"Missing path validation in organisation logo file construction allows path traversal."

Attack vector

An attacker who can influence an organisation field — most practically the organisation name — supplies path traversal sequences such as `../../../../AI-marketing` in that field. When `getOrgLogo()` is called, the filename is constructed as `$path . $org['Organisation'][$field] . '.png'`; the naive `file_exists()` check permits traversal, causing MISP to return an arbitrary `.png` or `.svg` file readable by the web server. No authentication is required if the endpoint is publicly exposed. [CWE-22]

Affected code

The vulnerable code resides in `OrganisationsController::getOrgLogo()` (app/Controller/OrganisationsController.php). It constructs organisation logo file paths by concatenating organisation-controlled fields (`id`, `name`, `uuid`) without validating that the resolved path stays within `APP . 'files/img/orgs/'`. A secondary XSS issue was fixed in `app/View/Themed/UiBeta/Events/index.ctp`.

What the fix does

The patch resolves the candidate path with `realpath()` and verifies it starts with the real path of the intended base directory (`$realBase . DS`). `realpath()` collapses `..` sequences and returns `false` for non-existent files, so crafted names like `../../../../etc/passwd` will either resolve outside the prefix (and be rejected) or resolve to a non‑existent file (and be rejected). This closes the traversal gap without changing the public API. The secondary XSS fix in the UI beta template uses `json_encode()` (which produces a proper JS string literal) wrapped in `h()` to prevent HTML‑attribute injection.

Preconditions

  • inputThe attacker must be able to create or modify an organisation record with a controlled name (or id/uuid) containing path traversal sequences.
  • networkThe `getOrgLogo` endpoint must be accessible (no additional authentication required beyond what the application exposes).

Generated on Jun 12, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

1

News mentions

0

No linked articles in our index yet.