All Advisories

dcm4chee-arc-light

Remote Code Execution via Vendor-Data Extraction

The archive can carry a vendor-data ZIP inside its own configuration, and unpacks it whenever configuration is loaded. Neither the names of the entries in that ZIP nor the directory they are unpacked into were constrained: the entry name was resolved against the unpack directory without a containment check, and the unpack directory is itself a configuration value written through the same interface. An attacker able to write archive configuration can therefore place a file at a path of their choosing, and by targeting the directory the application server watches for deployments, have it deployed and run as the archive service account.

Authored byVolker Schönefeld, Simon Weber2026-08-31
SeverityCriticalCVSS 9.8CVSS 3.1 VectorAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HCWECWE-22 (Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'))Productdcm4chee-arc-lightAffected VersionsAll 5.x releases up to and including 5.35.0.Fixed In5.35.1CVEPendingGHSAGHSA-hxq8-xgh3-4f76

Description

A dcm4che device can carry arbitrary binary vendor data in its configuration. When the configuration value dcmUnzipVendorDataToURI is set, the archive treats that blob as a ZIP and unpacks it into the named directory, both at startup and on every configuration reload. The extraction loop resolves each entry name against the unpack directory and writes it out:

ArchiveDeviceProducer.java:129-142

Path basePath = Paths.get(URI.create(StringUtils.replaceSystemProperties(unzipTo)));
ZipInputStream input = new ZipInputStream(new ByteArrayInputStream(vendorData[0]));
ZipEntry entry;
try {
while ((entry = input.getNextEntry()) != null) {
if (!entry.isDirectory()) {
Path filePath = basePath.resolve(entry.getName());
Files.createDirectories(filePath.getParent());
Files.copy(input, filePath, StandardCopyOption.REPLACE_EXISTING);
}
}
} catch (IOException e) {
LOG.error("Failed to extract Device Vendor Data", e);
}

View source →

Path.resolve() does not constrain its argument. An entry name containing traversal segments resolves to a path outside basePath, and an absolute entry name replaces it entirely. There is no normalize() call and no check that the result still starts with basePath, so the destination of each written file is decided by the ZIP rather than by the archive. Files.createDirectories(filePath.getParent()) then creates whatever intermediate directories the chosen path needs.

This is the first of two variants. The second survives the entry-name fix, because the unpack directory is not fixed either:

VariantAffectedControlled valueContainment
Traversing entry nameup to 5.34.3ZIP entry nameNone; resolve() without normalize() or a prefix check
Redirected unpack directory5.35.0dcmUnzipVendorDataToURIEntry names contained, but the base directory is configuration-controlled

Both variants terminate in the same place. The stock distribution runs on WildFly with the deployment scanner enabled against standalone/deployments, so a web application archive that appears in that directory is picked up and deployed without further action. The default unpack directory sits under the same application server home, which is what makes the traversal short. Code then runs as the operating-system account the archive runs under.

The configuration interface that carries both the vendor-data blob and the dcmUnzipVendorDataToURI value is the archive's own device configuration resource, and the reload that triggers extraction is exposed on its control resource. On the default deployment neither requires authentication (see the deployment note under Impact), so the whole sequence is available to an unauthenticated caller.

The fix rejects vendor-data ZIP entries that resolve outside the unpack directory, and separately constrains where the unpack directory may point, so neither part of the primitive remains reachable from configuration alone. The directory may sit under the application server's temporary subtree or entirely outside the application server home; what is refused is the rest of that home, and the deployments directory above all. The second half was addressed in a later release than the other findings in this batch, which is why this advisory carries a different fixed version.

dcm4chee-arc-light is the DICOM archive and image manager of the dcm4che project, used by hospitals, research groups, and imaging vendors as open infrastructure for storing and exchanging medical images. We appreciate the project's long-running work on that infrastructure and the care its maintainers took over this report. We reported this finding privately to J4Care in June 2026; they responded constructively and released a fix.

Impact

  • Code execution in the archive process carries the archive's own access to the imaging record it holds. The process is the custodian of the stored DICOM objects and of the database that indexes them, so studies and the patient identifiers attached to them can be read, altered, or deleted, and the credentials the archive holds for its own backing services are readable in that context.
  • Independently of the deployment step, the same primitive is an arbitrary file write as the archive service account. Files outside the deployment directory can be created or replaced, which reaches application server configuration and any startup script or trust store the account can write.
  • Severity is rated against the deployment the project's own documentation presents first, in which the configuration interface answers without authentication. Where the secured build is deployed instead, the configuration interface requires only the base role that the shipped low-privilege account already holds, so the chain remains reachable by any authenticated user rather than being closed.

Mitigation

Upgrade to dcm4chee-arc-light 5.35.1 or later, which rejects vendor-data ZIP entries resolving outside the unpack directory and constrains the unpack directory to the application server's temporary subtree or to a location entirely outside the application server home. Note that 5.35.0 closes only the first variant. Until upgraded, operators can reduce exposure by leaving dcmUnzipVendorDataToURI unset, which disables extraction entirely, by restricting the configuration and control interfaces and the LDAP configuration backend to trusted networks, and by disabling the application server's deployment scanner on installations that do not hot-deploy.

Defender's Checklist

  • Check whether vendor-data extraction is switched on at all.

    Extraction only happens when dcmUnzipVendorDataToURI is set on the archive device. If your deployment does not rely on vendor data, leaving it unset removes the code path. Confirm the current value in your LDAP or JSON configuration backend rather than assuming the default.

  • Upgrade to 5.35.1, not 5.35.0.

    5.35.0 fixes the traversing entry name but still allows the unpack directory to be redirected through configuration. Only 5.35.1 constrains where that directory may point, and note the shape of the constraint: a directory outside the application server home is still permitted, so a deployment that unpacks vendor data to its own path elsewhere on the filesystem keeps working. If you already moved to 5.35.0 for the other findings in this batch, this one is still open.

  • Restrict the configuration and control interfaces.

    Both variants start from a configuration write and a reload. The archive provides no way to restrict its device and control resources to administrators separately from ordinary users, so the boundary has to be enforced outside the application, at a reverse proxy or on the network. The LDAP configuration backend needs the same treatment, since writing configuration there reaches the same code path.

  • Turn off the deployment scanner where it is not needed.

    The step that converts a file write into code execution is the application server picking up an archive from its deployments directory. Installations that deploy once and do not hot-deploy can disable the scanner, which removes that step for this finding and for the storage-descriptor write covered in the related advisory.

  • Treat an exposed archive as having disclosed its configuration secrets.

    If the configuration interface was reachable from an untrusted network, assume the credentials held in archive configuration for the database, the storage backends, and the LDAP backend are known, and rotate them.

Severity Reasoning

AV:NThe configuration and control interfaces are HTTP resources of the archive, reachable from anywhere the archive is reachable.AC:LNo timing, race, or environmental preconditions. The default unpack directory and the deployment scanner are both stock configuration.PR:NRated against the deployment the project documents first, in which the configuration interface answers without authentication. On the secured build this becomes PR:L, giving 8.8.UI:NExtraction runs on configuration reload, which the same interface triggers.S:UImpact is bounded to the archive service account and what it can reach; the application server and the archive are the same security authority.C:HCode execution exposes stored imaging, the index database, and the credentials the archive holds for its backing services.I:HThe write primitive alone modifies files as the service account; code execution extends that to the imaging record.A:HThe same primitive replaces files the archive needs to run, and code execution can stop the service.

References

How We Can Help

Who We Are

The security researchers behind this advisory.

Dr. Simon Weber Profile

Dr. rer. nat. Simon Weber

Senior Pentester & MedSec Researcher

I evaluate your SaMD with the same industry-defining security insight I contributed to the BAK MV for the revision of the B3S standard.

  • PhD on Hospital Cybersecurity
  • Critical vulnerabilities found in hospital systems
  • Alumni of THB MedSec Research Group
  • gematik Security Hero
Volker Schönefeld Profile

Dipl.-Inf. Volker Schönefeld

Senior Application Security Expert

As a former CTO and developer turned pentester, I work alongside your team to uncover vulnerabilities and find solutions that fit your architecture.

  • 20+ years as CTO, 50M+ app downloads
  • Architected and secured large-scale IoT fleets
  • Certified Web Exploitation Specialist
  • gematik Security Hero

Looking for a Penetration Test?

Machine Spirits specializes in security assessments for medical devices and healthcare IT. From MDR penetration testing to C5 cloud compliance, we help MedTech companies meet regulatory requirements.