Injection

How to Fix Injection in Spring Boot [March 2026] [CVE-2018-1196]

[Updated 2026-03] Updated CVE-2018-1196

Overview

CVE-2018-1196 describes a symlink-based vulnerability in the embedded launch script that Spring Boot packaged with for running applications as Linux services (systemd or init.d). The script affected includes in Spring Boot 1.5.9 and earlier and 2.0.0.M1 through 2.0.0.M7, and when attacked, a malicious user with shell access to the run_user could exploit a symlink race to overwrite and take ownership of arbitrary files on the host system. This CWE-59 scenario arises when the script writes to a path that can be influenced by an attacker (via symlinks) and the process executes with elevated or sensitive permissions, enabling privilege escalation. The vulnerability is tied to how the embedded launcher interacts with the filesystem rather than the core Java application logic. See CVE-2018-1196 for specifics. In practice, an application packaged with the vulnerable embedded launch script could be installed as a system service, and if the run_user account is compromised or has shell access, an attacker could manipulate the file system layout to cause the launcher to overwrite critical files. This could result in loss of integrity, arbitrary file modification, or privilege escalation on the host. The issue is categorized under CWE-59 (Improper Link Resolution/Unsafe Link Following) and highlights the risk of relying on embedded tooling that interacts with system-level resources without robust permission checks and safe file handling. The remediation revolves around upgrading away from the vulnerable embedded launcher, or avoiding its use altogether in favor of standard OS service deployment mechanisms. By removing reliance on the embedded script, or by upgrading to a non-affected version, you reduce the attack surface. In Spring Boot, the recommended practice is to rely on the operating system's packaging mechanisms (systemd unit files or init.d scripts provided by the OS or your packaging tool) rather than the embedded script. This reduces the chance of symlink traversal, enforces proper ownership and permission boundaries, and lets you apply OS-specific hardening during service installation. In summary, the vulnerability manifests when an application is installed as a service using the embedded Spring Boot launcher and an attacker can influence the target path via a symlink. The fix is to upgrade to a fixed version (2.0.0.M8 or newer) or better, avoid the embedded launcher entirely and use OS-provided service deployment with tightly controlled file paths and permissions to prevent symlink-based overwrites.

Affected Versions

Spring Boot 1.5.9 and earlier; Spring Boot 2.0.0.M1 through 2.0.0.M7

Code Fix Example

Spring Boot API Security Remediation
// Vulnerable pattern (illustrative example showing path derived from input, not a safe practice)
public class LaunchScriptBinder {
    public static void main(String[] args) throws Exception {
        // Vulnerable: path depends on environment/user input, enabling symlink manipulation
        String runUser = System.getenv("RUN_USER");
        if (runUser == null) runUser = "root";
        java.nio.file.Path scriptDir = java.nio.file.Paths.get("/etc/systemd/system");
        java.nio.file.Path serviceUnit = scriptDir.resolve(runUser + ".service");
        String content = "[Unit]\nDescription=Demo App Service\n";
        java.nio.file.Files.write(serviceUnit, content.getBytes(java.nio.charset.StandardCharsets.UTF_8),
                java.nio.file.StandardOpenOption.CREATE, java.nio.file.StandardOpenOption.TRUNCATE_EXISTING);
        java.util.Set<java.nio.file.attribute.PosixFilePermission> perms =
                java.util.EnumSet.of(java.nio.file.attribute.PosixFilePermission.OWNER_READ,
                                      java.nio.file.attribute.PosixFilePermission.OWNER_WRITE,
                                      java.nio.file.attribute.PosixFilePermission.GROUP_READ,
                                      java.nio.file.attribute.PosixFilePermission.OTHERS_READ);
        java.nio.file.Files.setPosixFilePermissions(serviceUnit, perms);
    }
}

// Fixed pattern (do not base on untrusted input; use a fixed, trusted path and atomic operations)
public class LaunchScriptBinderFixed {
    public static void main(String[] args) throws Exception {
        // Fixed: use a known, trusted path
        java.nio.file.Path serviceUnit = java.nio.file.Paths.get("/etc/systemd/system/myapp.service");
        String content = "[Unit]\nDescription=Demo App Service\n";
        // Write to a temp file first, then atomically move to final destination
        java.nio.file.Path temp = java.nio.file.Files.createTempFile("myapp", ".service");
        java.nio.file.Files.write(temp, content.getBytes(java.nio.charset.StandardCharsets.UTF_8),
                java.nio.file.StandardOpenOption.CREATE, java.nio.file.StandardOpenOption.TRUNCATE_EXISTING);
        java.nio.file.Files.setPosixFilePermissions(temp,
                java.util.EnumSet.of(java.nio.file.attribute.PosixFilePermission.OWNER_READ,
                                     java.nio.file.attribute.PosixFilePermission.OWNER_WRITE,
                                     java.nio.file.attribute.PosixFilePermission.GROUP_READ,
                                     java.nio.file.attribute.PosixFilePermission.OTHERS_READ));
        java.nio.file.Files.move(temp, serviceUnit, java.nio.file.StandardCopyOption.ATOMIC_MOVE,
                java.nio.file.StandardCopyOption.REPLACE_EXISTING);
    }
}

CVE References

Choose which optional cookies to allow. You can change this any time.