In a standalone program, System.exit() ends your process. In a web application running inside a J2EE container, it ends the container, and every other application hosted there. CWE-382 flags exactly this: a J2EE application uses System.exit(), which also shuts down its container.
MITRE's wording is blunt: it is never a good idea for a web application to attempt to shut down the application container. Any reachable path to such a function is an avenue for denial of service.
How it happens
Developers add an exit call as a "fail fast" reaction to a bad config, a failed health check or a hidden admin endpoint.
protected void doGet(HttpServletRequest req, HttpServletResponse res) {
if ("true".equals(req.getParameter("shutdown"))) {
System.exit(0); // takes down the container and every app in it
}
}
Even without a debug parameter, an error branch that calls exit can be triggered by crafted input.
What an attacker gains
MITRE lists one consequence: availability, through crash, exit or restart. One request can stop the service for all users.
How to find it
MITRE says automated static analysis can find some instances. A plain grep for System.exit and Runtime.getRuntime().exit or halt across web modules is a good first check.
How to fix it
- Do not call methods that make the virtual machine exit from a web application, and do not throw Throwables up to the application server, since that can hurt the container.
- If a shutdown function must exist, make it a privileged function available only to a properly authorized administrative user (MITRE's separation of privilege strategy).
- Non-web programs may keep a System.exit() in main(), but should generally not call it from elsewhere.
Handle the failure instead: log it, return an error response, and let the container's own lifecycle tools decide about restarts.
Quick check
Is System.exit() fine in a command line tool?
Generally yes in main(). MITRE advises against calling it from other locations in the code.