Prevention of technical information leakage from system error traces
import javax.servlet.*
import javax.servlet.http.*
import java.io.IOException
class VulnerableServlet : HttpServlet() {
@Throws(ServletException::class, IOException::class)
override fun doGet(request: HttpServletRequest, response: HttpServletResponse) {
try {
// some risky operation
throw Exception("This is a forced exception")
} catch (e: Exception) {
e.printStackTrace(response.writer)
}
}
}
The following Kotlin servlet contains a security vulnerability that leads to technical information leakage through stack traces.
In the
doGet
method, an exception is intentionally thrown to simulate a scenario where an error occurs. The catch block then prints the stack trace directly to the HTTP response using
e.printStackTrace(response.writer)
.
This is a serious issue because the stack trace exposes internal details of the application, such as class names, method signatures, and even system properties. If an attacker can trigger this error, they could gather useful information about the system to plan further attacks.
To mitigate this risk, the exception should be logged securely instead of being exposed to the user.
import javax.servlet.*
import javax.servlet.http.*
import java.io.IOException
import java.util.logging.Level
import java.util.logging.Logger
class SecureServlet : HttpServlet() {
companion object {
private val LOGGER = Logger.getLogger(SecureServlet::class.java.name)
}
@Throws(ServletException::class, IOException::class)
override fun doGet(request: HttpServletRequest, response: HttpServletResponse) {
try {
// some risky operation
throw Exception("This is a forced exception")
} catch (e: Exception) {
LOGGER.log(Level.SEVERE, e.message, e)
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occurred while processing your request. Please try again later.")
}
}
}
The secure version of the code properly handles errors and prevents technical information leakage. Key improvements include:
1. Preventing stack trace exposure: The
e.printStackTrace(response.writer)
line is removed to avoid leaking internal system details.
2. Implementing proper logging: A
Logger
instance is used to record exceptions securely on the server side.
3. Using a generic error message: Instead of showing detailed error information to the client, a standardized error response is sent.
4. Ensuring centralized error handling: Logging is handled in a consistent way, making debugging easier while improving security.
5. Keeping sensitive information private: Error details remain in server logs instead of being exposed to users.