Safeguard
Vulnerability Analysis

Apache Shiro remember-me cookie deserialization RCE (CVE-2016-4437)

Apache Shiro's default rememberMe cipher key enables unauthenticated Java deserialization RCE. Here's how CVE-2016-4437 works and how to fix it.

Vikram Iyer
Cloud Security Engineer
8 min read

A hard-coded, publicly known AES cipher key baked into Apache Shiro's "remember me" cookie handling lets an unauthenticated attacker forge a cookie that Shiro will happily decrypt and deserialize — turning a login convenience feature into a remote code execution primitive. Tracked as CVE-2016-4437 and widely nicknamed Shiro-550 by the security community, this vulnerability has powered years of mass exploitation against internet-facing Java applications, and it remains one of the most common findings security teams run into when auditing legacy Java stacks. If your organization runs any product built on Apache Shiro — homegrown Java apps, admin panels, or third-party software that vendored Shiro under the hood — this is a vulnerability worth checking for by name, not just by version number.

What the vulnerability actually is

Apache Shiro is a widely used Java security framework that handles authentication, authorization, cryptography, and session management. One of its convenience features, RememberMeManager, persists a user's identity across sessions by serializing the principal object, encrypting the serialized bytes with AES in CBC mode, Base64-encoding the result, and storing it in a cookie named rememberMe. On the next request, Shiro reverses the process: Base64-decode, decrypt, then deserialize the bytes back into a Java object.

The defect is in how the AES key is chosen. Prior to version 1.2.5, if an application did not explicitly configure its own cipher key, Shiro fell back to a default, hard-coded 128-bit AES key that was published in Shiro's own source code and documentation. Because the key was static and public, anyone could construct their own malicious serialized Java object — typically a gadget chain from a library like Commons-Collections, Groovy, or similar — encrypt it with that well-known default key, Base64-encode it, and drop it into the rememberMe cookie of an HTTP request. Shiro's server-side code decrypts the attacker-supplied bytes without any integrity check tying them to a legitimate session, then calls Java's native deserialization on them. If a suitable gadget chain is present anywhere on the application's classpath, that deserialization executes attacker-chosen code with the privileges of the Java process — full unauthenticated remote code execution, no credentials required.

This is a textbook example of the broader "insecure Java deserialization" vulnerability class that also produced high-profile bugs in Jenkins, WebLogic, and Jackson-based services. What makes the Shiro variant distinctive — and durable — is that the entry point is a single, unauthenticated, unauthenticated cookie value, which makes it trivially scriptable and easy to scan for at internet scale.

Affected versions and components

  • Apache Shiro versions prior to 1.2.5 are affected when the deploying application relies on Shiro's default rememberMe cipher key instead of configuring a custom one.
  • The risk is not strictly eliminated by upgrading alone: Shiro 1.2.5 and later ship without a usable default key baked in for this purpose in the same way, but the underlying design still depends on the operator explicitly configuring a strong, unique cipherKey for CookieRememberMeManager. Deployments that copy-pasted a "sample" key from tutorials or Stack Overflow answers remain just as exposed as deployments running the genuinely vulnerable default.
  • Any product, CMS, admin console, or internal tool that embeds Shiro — directly or transitively through a dependency — inherits this exposure. Shiro has historically shipped inside numerous Chinese enterprise software stacks, OA (office automation) systems, and Java-based admin portals, which is a large part of why exploitation of this bug has been so persistent and geographically concentrated in mass-scanning campaigns.
  • The vulnerability requires only that rememberMe functionality be enabled and reachable over HTTP/HTTPS; no prior authentication or session token is needed to send the crafted cookie.

CVSS, EPSS, and exploitation context

NVD scores CVE-2016-4437 with a CVSS v2 base score of 7.5 (High) (AV:N/AC:L/Au:N/C:P/I:P/A:P), reflecting the original scoring conventions of 2016. Because the practical outcome is unauthenticated remote code execution, many third-party scanners and vulnerability databases re-score it under CVSS v3.x closer to 9.8 (Critical), and we'd encourage teams to prioritize it as critical regardless of which legacy score appears in a given feed.

EPSS (Exploit Prediction Scoring System) data for this CVE has repeatedly sat in the higher percentiles relative to the broader vulnerability population, which tracks with reality: public, one-click exploit tooling for Shiro-550 has circulated openly since 2019, and mass internet scanning for vulnerable rememberMe endpoints has been a fixture of opportunistic attacker and botnet activity for years. As of this writing, CVE-2016-4437 does not appear on CISA's Known Exploited Vulnerabilities (KEV) catalog, but the absence of a KEV listing should not be read as an absence of real-world risk — threat intel telemetry, honeypot data, and incident response case studies have documented sustained exploitation of this exact flaw well outside any single catalog's scope, including use by cryptomining botnets and as an initial-access vector in broader intrusions.

Timeline

  • Discovered and reported to the Apache Shiro security team, early 2016 — researchers identified that Shiro's default rememberMe cipher key was static, publicly known, and exploitable for deserialization-based RCE.
  • June 2016 — Apache Shiro 1.2.5 released. The release addressed the immediate default-key exposure and Apache published guidance urging all deployments to configure their own unique cipher key rather than rely on any bundled default.
  • CVE-2016-4437 assigned and published by MITRE/NVD, formally cataloging the issue for vulnerability management tooling.
  • 2019 — public "Shiro-550" exploit tooling proliferates. Community-published scripts automated the full attack chain (cookie forgery, gadget chain selection, payload delivery), causing a sharp uptick in mass scanning and opportunistic exploitation across exposed Java applications.
  • 2020–present — continued active exploitation. Security vendors and CERTs have repeatedly flagged Shiro-550 exploitation in the wild, particularly against Java-based OA systems, CMS platforms, and internal admin tools that embed old or misconfigured Shiro versions, often as a precursor to cryptomining, webshell deployment, or lateral movement.

Remediation steps

  1. Upgrade Apache Shiro to the latest supported release. Don't stop at 1.2.5 — treat that as a floor, not a target; later releases carry additional hardening and dependency fixes relevant to the deserialization attack surface.
  2. Explicitly configure a strong, randomly generated cipher key for CookieRememberMeManager rather than relying on any default or a key copied from public documentation, tutorials, or forum posts. Generate a fresh, unique AES key (128-bit minimum) per application/environment and store it in a secrets manager, not in source control.
  3. Disable the rememberMe feature entirely if your application doesn't genuinely need persistent-login cookies. The smallest attack surface is the feature you never turned on.
  4. Rotate the cipher key on a defined schedule and immediately upon any suspected exposure of configuration files, source repositories, or backups that might contain it.
  5. Reduce or eliminate known deserialization gadget chains from the classpath — audit for libraries like older Commons-Collections, Groovy, or other historically abused gadget sources, and upgrade or remove them where they aren't required at runtime.
  6. Add detection for the attack pattern, not just the vulnerable version: monitor for oversized or malformed rememberMe cookie values, and where feasible inspect decoded cookie payloads for the Java serialization magic bytes (0xAC 0xED) as a strong signal of an exploitation attempt.
  7. Inventory every place Shiro is running, including inside third-party products and vendored/bundled dependencies — this bug is notorious for hiding inside software teams didn't realize shipped a Java web stack at all.
  8. Constrain outbound network egress from application hosts where practical, since successful RCE via this chain is frequently used to pull second-stage payloads or open reverse shells.

How Safeguard Helps

Finding "Shiro is somewhere in our estate" is the easy part; finding out whether the vulnerable rememberMe code path is actually configured, reachable, and exploitable in your specific deployment is where most teams get stuck — and where alert fatigue sets in. Safeguard's reachability analysis traces whether the vulnerable CookieRememberMeManager deserialization path is actually invoked in your application's real execution paths, so you can separate "Shiro is on the classpath" from "this cookie handler is genuinely exposed to unauthenticated requests." Griffin AI, Safeguard's AI-driven triage layer, correlates that reachability signal with your CVSS/EPSS/KEV context to help prioritize CVE-2016-4437 against everything else competing for your team's attention, instead of treating every legacy Java finding as equally urgent. Continuous SBOM generation and ingestion give you a single source of truth for every service, container, and vendored dependency that pulls in Shiro — including transitive copies buried inside third-party products — so this class of finding doesn't quietly reappear after the next release. And where a fix is available, Safeguard can open an auto-fix pull request that bumps the Shiro version and flags the missing cipher-key configuration, turning a sprawling remediation effort into a reviewable diff your team can merge with confidence.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.