Summary
An unsafe JavaScript evaluation vulnerability (Eval Injection) in the Markdown rendering engine allows any user capable of interacting with the AI chat interface to execute arbitrary JavaScript in the browsers of other users, including administrators. This leads to a severe Stored Cross-Site Scripting (XSS) vulnerability.
Details
The vulnerability stems from the ui/src/components/markdown/EchartsRander.vue component, which is responsible for rendering Apache Echarts graphs embedded within Markdown responses using the custom <echarts_rander> tag.
When the Markdown renderer extracts the JSON content from an <echarts_rander> tag, it passes the object to this component. If the JSON object contains "actionType": "EVAL", the evalParseOption() function blindly passes the "option" field to JavaScript's native eval() function without any escaping or sanitization.
function evalParseOption(option_json: any) {
if (option_json.style) {
style.value = option_json.style
}
const option = {}
tmp.value = echarts
eval(option_json.option) // <-- CRITICAL VULNERABILITY
return option
}
Because the payload inside the <echarts_rander> tag is not neutralized by MdPreview (HTML sanitizers do not parse the JSON inside this custom tag), an attacker can easily bypass all Rich Text sanitizers and achieve direct code execution in the victim's DOM context.
Summary
An unsafe JavaScript evaluation vulnerability (Eval Injection) in the Markdown rendering engine allows any user capable of interacting with the AI chat interface to execute arbitrary JavaScript in the browsers of other users, including administrators. This leads to a severe Stored Cross-Site Scripting (XSS) vulnerability.
Details
The vulnerability stems from the ui/src/components/markdown/EchartsRander.vue component, which is responsible for rendering Apache Echarts graphs embedded within Markdown responses using the custom <echarts_rander> tag.
When the Markdown renderer extracts the JSON content from an <echarts_rander> tag, it passes the object to this component. If the JSON object contains "actionType": "EVAL", the evalParseOption() function blindly passes the "option" field to JavaScript's native eval() function without any escaping or sanitization.
function evalParseOption(option_json: any) {
if (option_json.style) {
style.value = option_json.style
}
const option = {}
tmp.value = echarts
eval(option_json.option) // <-- CRITICAL VULNERABILITY
return option
}
Because the payload inside the <echarts_rander> tag is not neutralized by MdPreview (HTML sanitizers do not parse the JSON inside this custom tag), an attacker can easily bypass all Rich Text sanitizers and achieve direct code execution in the victim's DOM context.