There is a fix for rendering multi-line tooltips for config node validation errors in Node-RED, this explains how the approach preserves security against Cross-Site Scripting (XSS) vulnerabilities.
1. Problem: HTML Escaping and Usability
- Previously, config node error tooltips used a string with
<br>tags to indicate line breaks. - Due to the popover implementation, all function-returned strings were rendered using
.text(), escaping HTML, so<br>appeared as literal text. - Rendering as HTML (with
.html()) would allow line breaks, but would also introduce XSS risk if any part of the message was user-controlled.
2. The Fix: Array-based Multi-line Tooltips
Implementation
- The error message is now passed as an array:
- The first element is the main error label (e.g., "Invalid properties:").
- Each subsequent element is a validation error (e.g.,
" - authUrl").
- The popover script was updated to detect arrays:
- Each array element is rendered as a text node.
- A line break (
<br>) is inserted between each line. - No HTML is interpreted from the error strings themselves.
Example
const errorMsg = [
RED._("editor.errors.invalidProperties"),
...node.validationErrors.map(e => " - " + e)
];
RED.popover.tooltip(target, errorMsg);
Popover rendering logic:
if (typeof result === 'string') {
contentDiv.text(result);
} else if (Array.isArray(result)) {
result.forEach(function(line, idx) {
if (idx > 0) contentDiv.append(document.createElement('br'));
contentDiv.append(document.createTextNode(line));
});
} else {
contentDiv.append(result);
}
3. Security: XSS Protection
- No HTML is ever interpreted from the error message array.
- Each line is rendered using
document.createTextNode(line), which escapes all HTML and JavaScript. - Even if a validation error contains user-controlled content (e.g., a property name like
<img src=x onerror=alert(1)>), it will be displayed as plain text, not executed. - This approach is as safe as the original
.text()rendering, but allows for visually clean, multi-line tooltips.
4. Result
- Tooltips for config node errors now display each error on its own line, improving readability and usability.
- The code remains robust against XSS, as no user input is ever rendered as HTML.
- This pattern can be safely reused for any tooltip content that requires multi-line display and may include user input.
5. References
Is this something that is worth creating a PR for, I figure it is a non-breaking change.