Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/mcp/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func (s *Server) registerAppTools() {
// need typed handler generics. Each call registers both tool and resource
// (the resource half is no different from a no-args app).
s.registerInsightsView()
s.registerUserView()
}

// registerAppResources registers the ui:// resource half of every MCP App.
Expand Down
12 changes: 8 additions & 4 deletions internal/mcp/apps_html/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,23 @@
"use strict";

// --- Safe DOM helpers ---
// Text-content-only: callers set className/textContent or inline style
// properties (string CSS values from a fixed palette). Anything else
// is dropped rather than forwarded to setAttribute, so the helper can
// never become an XSS surface for href/onclick/srcdoc/etc.
function el(tag, attrs, children) {
var node = document.createElement(tag);
if (attrs) {
Object.keys(attrs).forEach(function(k) {
if (k === 'className') node.className = attrs[k];
else if (k === 'textContent') node.textContent = attrs[k];
else node.style[k] = attrs[k];
if (k === 'className') node.className = String(attrs[k]);
else if (k === 'textContent') node.textContent = String(attrs[k]);
else node.style[k] = String(attrs[k]);
});
}
if (children) {
children.forEach(function(c) {
if (typeof c === 'string') node.appendChild(document.createTextNode(c));
else if (c) node.appendChild(c);
else if (c instanceof Node) node.appendChild(c);

Check failure

Code scanning / CodeQL

Client-side cross-site scripting High

Cross-site scripting vulnerability due to
user-provided value
.
});
}
return node;
Expand Down
11 changes: 7 additions & 4 deletions internal/mcp/apps_html/insights.html
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,20 @@
return d.toISOString().slice(5, 16).replace("T", " "); // MM-DD HH:MM
}

// Text-content-only DOM builder: callers only set className/textContent
// and pass already-constructed Nodes as children. Anything else is a
// bug — drop unknown attribute keys rather than forwarding them to
// setAttribute (which would open an XSS surface for href/onclick/etc.).
function el(tag, attrs, children) {
var n = document.createElement(tag);
if (attrs) Object.keys(attrs).forEach(function(k){
if (k === "className") n.className = attrs[k];
else if (k === "textContent") n.textContent = attrs[k];
else n.setAttribute(k, attrs[k]);
if (k === "className") n.className = String(attrs[k]);
else if (k === "textContent") n.textContent = String(attrs[k]);
});
if (children) children.forEach(function(c){
if (c == null) return;
if (typeof c === "string") n.appendChild(document.createTextNode(c));
else n.appendChild(c);
else if (c instanceof Node) n.appendChild(c);

Check failure

Code scanning / CodeQL

Client-side cross-site scripting High

Cross-site scripting vulnerability due to
user-provided value
.
});
return n;
}
Expand Down
Loading
Loading