T09 · Insecure Skill Coding Practices
- Location
plugin/ui.html:135- Finding
DOM XSS Through Unescaped Figma Node Names
- Content
View full analysis
0) { var h = ''; msg.nodes.forEach(function(n) { h += '' + n.name + ' ' + n.type + ''; }); selectionInfo.innerHTML = h; } else { selectionInfo.innerHTML = 'None'; } return; } ``` The attacker-controlled node name originates from the active Figma selection: ```javascript var selArray = figma.currentPage.selection.map(function(n) { var r = {}; r.id = n.id; r.name = n.name; r.type = n.type; r.x = n.x; r.y = n.y; r.width = n.width; r.height = n.height; return r; }); var selMsg = {}; selMsg.nodes = selArray; postUI("selection-update", selMsg); ``` ### Technical Analysis The plugin concatenates `n.name` and `n.type` into an HTML string and assigns it to `selectionInfo.innerHTML`. Figma node names can be influenced by document collaborators or imported content. No HTML escaping, sanitization, or trusted-type enforcement is applied before the value reaches the DOM sink. If active HTML content or an event-handler payload is accepted by the plugin UI runtime, selecting a maliciously named node can execute JavaScript in the plugin UI context. The message listener also accepts `event.data` without checking `event.source`, further weakening the UI trust boundary. Code executing in this UI can access the existing `parent.postMessage` bridge: ``` ...[truncated 1555 chars]- Remediation
View remediation
