CVE-2026-40987 - Spring Integration remote file sync arbitrary write
Spring Integration remote file synchronizers accepted server-supplied filenames
without canonicalizing the resolved local path. If an application syncs from an
FTP, SFTP, or SMB endpoint it does not fully trust, a malicious server can
place files outside the configured localDirectory, overwriting arbitrary
application files with attacker-controlled content.
The real boundary is not just “package installed” but “this code pulls remote files onto a writable filesystem path.” Teams that sync into plugin folders, script directories, config mounts, or deployment workspaces have the highest risk.
When to use it
Use this recipe when a Java/Spring application uses Spring Integration remote file synchronizers to pull files from FTP, SFTP, SMB, or other remote file systems. It is designed for source-code remediation, canonical path containment, remote-server trust review, and evidence that server-supplied filenames cannot write outside the configured local directory.
Inputs
- Spring Integration version, dependency tree, remote file synchronizer config,
localDirectory, remote server trust model, and deployment filesystem layout. - Source/config paths that sync remote files, apply filename filters, resolve local paths, write files, or process synced files after download.
- Regression fixtures for traversal filenames, absolute paths, symlinks, benign filenames, denied out-of-root writes, and post-sync processing.
- Boundary evidence: writable directories, plugin/script/config paths, remote server ownership, credentials, logs, and rollout owner.
Affected versions
- Vulnerable package:
org.springframework.integration:spring-integration-*in Spring Integration5.5.0-5.5.20,6.3.0-6.3.14,6.4.0-6.4.11,6.5.0-6.5.8,7.0.0-7.0.4 - Fixed versions:
5.5.21,6.3.15,6.4.12,6.5.9,7.0.5 - Affected surface: inbound or outbound remote file synchronizers that materialize server-controlled filenames under a local directory
Indicator-of-exposure
- The repository uses Spring Integration FTP, SFTP, or SMB adapters.
- Remote sync flows write into a local workspace, upload staging area, processing inbox, plugin directory, or any path later consumed by the application or operators.
- Filename filtering assumes the remote endpoint is trusted and does not canonicalize the final resolved local path.
- The synced filesystem location is writable by the application and security relevant if overwritten.
Quick checks:
rg -n "spring-integration|SftpInboundFileSynchronizer|FtpInboundFileSynchronizer|AbstractInboundFileSynchronizer|localDirectory|remoteDirectory|InboundFileSynchronizingMessageSource|smb" .
mvn -q dependency:tree | rg "spring-integration"
gradle dependencies --configuration runtimeClasspath | rg "spring-integration"
Windows:
rg -n "spring-integration|SftpInboundFileSynchronizer|FtpInboundFileSynchronizer|AbstractInboundFileSynchronizer|localDirectory|remoteDirectory|InboundFileSynchronizingMessageSource|smb" .
mvn -q dependency:tree | rg "spring-integration"
gradle dependencies --configuration runtimeClasspath | rg "spring-integration"
Remediation strategy
- Upgrade Spring Integration to the fixed line for the branch you support.
- Review every sync flow that writes remote files locally and confirm the final path stays under the intended root after normalization and symlink resolution.
- Add regression tests that reject traversal-like or absolute remote filenames without contacting a live hostile file server.
- If upgrade is temporarily blocked, wrap the local file resolution step with an explicit canonical-path check and fail closed on mismatch.
- Treat the upstream file server as untrusted until proven otherwise; narrow its write scope and avoid syncing into executable or configuration directories.
The prompt
Model context: this prompt was generated by GPT 5.5 Extra High reasoning.
You are remediating CVE-2026-40987, where Spring Integration remote-file
synchronizers can write attacker-controlled filenames outside the configured
local directory. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades Spring Integration, hardens
local path resolution, adds safe regression checks, and documents operator
actions, or
- TRIAGE.md if this repository does not control an affected Spring Integration
remote file synchronization path.
## Rules
- Scope only CVE-2026-40987 and directly related filename-to-local-path logic.
- Treat remote file contents, synced business data, credentials, and filesystem
layout as sensitive.
- Do not connect to hostile file servers or write proof-of-concept traversal
files into live environments.
- Do not silence the advisory by disabling whole integrations unless that is the
documented containment chosen by maintainers.
- Do not auto-merge.
## Steps
1. Inventory every Spring Integration remote file adapter, synchronizer, poller,
XML config, Java config, manifest, lockfile, image, and SBOM in scope.
2. Determine which targets resolve vulnerable Spring Integration versions.
3. Trace each remote filename into its final local filesystem destination.
4. Identify whether synced files land in executable paths, config paths, shared
mounts, or other sensitive directories.
5. If the repository does not control an affected sync path, stop with
`TRIAGE.md` listing checked files, runtime owner, and required fixed version.
6. Upgrade all controlled Spring Integration references to the fixed release for
the supported branch. Refresh lockfiles, BOMs, images, and generated reports.
7. Ensure local path resolution fails closed after canonicalization:
- the resolved path must stay under the configured sync root;
- absolute paths are rejected;
- traversal segments do not escape the root;
- symlink handling does not reintroduce escape paths.
8. Add safe tests that verify malicious filenames are rejected and valid
filenames still sync as expected.
9. Add a PR body section named `CVE-2026-40987 operator actions` that states:
- versions before and after;
- which sync flows were affected;
- whether any destinations were security-sensitive;
- whether temporary containment was applied;
- which validation commands passed.
10. Run available validation: dependency resolution, unit tests, integration
tests with local fixtures, container build, and security scans.
11. Use PR title:
`fix(sec): remediate CVE-2026-40987 in Spring Integration`.
## Stop conditions
- No affected Spring Integration remote file sync path is controlled here.
- Upgrade requires a broader platform migration outside scope.
- Verification would require writing exploit files into shared or production
paths.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Output contract
- A reviewer-ready PR or change request that upgrades Spring Integration, canonicalizes server-supplied filenames, adds containment tests, and documents sync pipeline cleanup.
- Or a
TRIAGE.mdfile that lists inspected files/config, owner, observed version, remote-sync boundary, writable paths, required fix, and residual risk. - The output must include exact validation commands and must not overwrite real application files, expose credentials, or sync from production endpoints.
Verification - what the reviewer looks for
- No controlled build resolves a vulnerable Spring Integration line.
- Remote filenames cannot escape the configured local sync root after normalization.
- Tests cover traversal, absolute-path, and normal filename cases.
- Operator notes identify any flows that still require external containment.
Watch for
- Bumping only one Spring Integration module while another transitive pin keeps the old vulnerable line.
- Canonicalizing one path check but later writing with a different unresolved path.
- Syncing into directories that are later executed, sourced, or deployed.
Related recipes
- Source code attack surface map
- Source code secrets and data exposure audit
- Source code supply chain build integrity audit
- SAST finding triage and fix
References
- Spring advisory: https://spring.io/security/cve-2026-40987/
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-40987