Issues addressed in 2.8.6.
Versions Affected: before 2.8.6.
Description: When processing topology credentials submitted via the Nimbus Thrift API, Storm deserializes the base64-encoded TGT blob using ObjectInputStream.readObject() without any class filtering or validation. An authenticated user with topology submission rights could supply a crafted serialized object in the "TGT" credential field, leading to remote code execution in both the Nimbus and Worker JVMs.
Mitigation: 2.x users should upgrade to 2.8.6.
Users who cannot upgrade immediately should monkey-patch an ObjectInputFilter allow-list to ClientAuthUtils.deserializeKerberosTicket() restricting deserialized classes to javax.security.auth.kerberos.KerberosTicket and its known dependencies.
If you are unable to update, monkey-patching can be done by replacing the affected class in the Storm client JAR with the changes from this commit, either by:
.class file from the 2.8.6 Storm release (no breaking changes in this class) and replacing it in the existing JAR:
jar xf storm-client-2.8.6.jar org/apache/storm/security/auth/ClientAuthUtils.classjar uf storm-client-2.8.5.jar org/apache/storm/security/auth/ClientAuthUtils.classjar tf storm-client-2.8.6.jar | grep ClientAuthUtils
Credit: This issue was discovered by K.
Versions Affected: before 2.8.6.
Description: The Storm UI visualization component interpolates topology metadata including component IDs, stream names, and grouping values directly into HTML via innerHTML in parseNode() and parseEdge() without sanitization at any layer. An authenticated user with topology submission rights could craft a topology containing malicious HTML/JavaScript in component identifiers (e.g., a bolt ID containing an onerror event handler). This payload flows through Nimbus → Thrift → the Visualization API → vis.js tooltip rendering, resulting in stored cross-site scripting.
In multi-tenant deployments where topology submission is available to less-trusted users but the UI is accessed by operators or administrators, this enables privilege escalation through script execution in an admin's browser session.
Mitigation: 2.x users should upgrade to 2.8.6.
Users who cannot upgrade immediately should monkey-patch storm-webapp/src/main/webapp/js/visualization.js as follows.
Step 1. Add the following helper function after the existing tooltipElement() function:
function escapeHtml(str) {
return String(str)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
Step 2. In parseNode(), replace the title construction and label in the node object:
var safeNodeId = escapeHtml(nodeId);
var safeCapacity = escapeHtml(nodeJson[":capacity"]);
var safeLatency = escapeHtml(nodeJson[":latency"]);
var title = tooltipElement([
{ text: safeNodeId, bold: true },
{ text: "Capacity: " + safeCapacity },
{ text: "Latency: " + safeLatency }
])
var node = {
"id": nodeId, // keep raw — vis.js uses this as an internal key
"label": safeNodeId,
...
Step 3. In parseEdge(), replace the visNS.edges.update() call:
visNS.edges.update({
"id": id,
"from": edgeJson[":component"], // keep raw — vis.js node reference key
"to": sourceId, // keep raw — vis.js node reference key
"label": escapeHtml(edgeJson[":stream"]),
"title": tooltipElement([
{ text: "From: " + escapeHtml(edgeJson[":component"]) },
{ text: "To: " + escapeHtml(sourceId) },
{ text: "Grouping: " + escapeHtml(edgeJson[":grouping"]) }
])
});
To deploy the patched file, replace it inside storm-webapp-2.8.5.jar, found in the lib-webapp directory of your Storm installation. Storm runs embedded Jetty and serves static resources directly from this JAR:
# Check the exact internal path first
jar tf lib-webapp/storm-webapp-2.8.5.jar | grep visualization.js
# Recreate the directory structure to match (e.g. public/js/)
mkdir -p public/js
cp visualization.js public/js/visualization.js
# Replace in the JAR
jar uf lib-webapp/storm-webapp-2.8.5.jar public/js/visualization.js
Restart the Storm UI process after replacing the file.
As a defense-in-depth measure, restrict topology submission to trusted users via Nimbus ACLs.
Credit: This issue was discovered while investigating another report by K.