Safeguard
Application Security•

CWE-594: J2EE Sessions Holding Unserializable Objects

Under load, J2EE containers flush session objects to disk. If those objects are not Serializable, requests fail and data corrupts. How to avoid it.

Safeguard Security Team
2 min read

CWE-594 is a Java web application weakness. When a J2EE container writes unserializable objects to disk, there is no guarantee the write will complete.

How it happens

Under heavy load, most J2EE application frameworks flush objects to disk to manage memory for incoming requests. Session scoped objects, and even application scoped objects, can be written out when needed.

The framework does the writing, but it does not enforce that those objects are serializable. So a class that was never meant to be persisted can sit in the session for months without trouble, until traffic pushes the container to write it out and serialization fails.

// Vulnerable pattern: class does not implement Serializable
public class CartHelper {
    private java.sql.Connection conn;   // not serializable either
}

session.setAttribute("helper", new CartHelper());

What an attacker gains

MITRE says an attacker may be able to mount a denial of service by sending enough requests to force the server to save objects to disk. The consequences recorded are corrupted data in the unserializable objects (integrity) and a possible system crash (availability).

How to find it

Static analysis can list the types passed to setAttribute on session and application scope and check whether each implements java.io.Serializable. Load testing with a deliberately low memory ceiling is the runtime check: if the container is forced to passivate sessions, failures show up in your test environment, not production.

How to fix it

MITRE's guidance applies at design and implementation time: all objects that become part of session and application scope must implement the java.io.Serializable interface, so that containing objects are serializable too.

public class CartHelper implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
    private transient java.sql.Connection conn; // reacquire after restore
}

Keep sessions small. Store identifiers and small value objects, and look up heavy resources when needed instead of parking them in scope.

Quick check

Who enforces that session objects are serializable? Not the framework. It writes objects to disk when required but does not check they can be serialized, so the application must make them Serializable.

Sources

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.