
☣️ इस रिपॉज़िटरी में CVE-2024-34312 का विवरण और प्रूफ ऑफ कॉन्सेप्ट (PoC) शामिल है
Moodle के लिए वर्चुअल प्रोग्रामिंग लैब v4.2.3 तक में इसके IDE घटक के माध्यम से एक क्रॉस-साइट स्क्रिप्टिंग (XSS) कमजोरी पाई गई।
ब्राउज़र जेल सर्वर पर चल रहे एक वेबसॉकेट से सीधे जुड़ता है। वेबसॉकेट के माध्यम से, जेल सर्वर ब्राउज़र को सीधे संदेश भेज सकता है। ये संदेश ब्राउज़र द्वारा पार्स किए जाते हैं और "executionActions" द्वारा संभाले जाते हैं। "run:browser" क्रिया अविश्वसनीय इनपुट के साथ HTML को जोड़ने और पृष्ठ बॉडी में इंजेक्ट करने के कारण XSS के प्रति संवेदनशील है। इसका दुरुपयोग एक समझौता किए गए जेल सर्वर द्वारा XSS के माध्यम से मूडल इंस्टेंस पर प्रशासनिक पहुंच प्राप्त करने के लिए किया जा सकता है।
एक हमलावर जो अविश्वसनीय जेल सर्वर को नियंत्रित करता है, एक दुर्भावनापूर्ण जेल सर्वर स्थापित कर सकता है जो वर्चुअल प्रोग्रामिंग लैब का उपयोग करने वाले किसी भी उपयोगकर्ता को दुर्भावनापूर्ण पेलोड भेजता है, जिससे XSS ट्रिगर होता है।
एक उदाहरण पेलोड इस प्रकार दिखेगा: run:browser:test\">test</a><script>alert(1)</script><a href=\"test\". इसके परिणामस्वरूप <script>alert(1)</script> DOM में शामिल हो जाएगा, जिससे alert(1) निष्पादित होगा।

vplide.js में कमजोर कोड इसे कमांड के रूप में व्याख्या करता है और इसके दूसरे तर्क (तर्क : द्वारा अलग किए जाते हैं) को सीधे DOM में जोड़ता है:
executionActions = {
// ...
'run': function(content, coninfo, ws) {
var parsed = /^([^:]*):?(.*)/i.exec(content);
var type = parsed[1];
if (type == 'terminal' || type == 'webterminal') {
// ...
} else if (type == 'vnc') {
// ...
} else if (type == "browser") {
var URL = (coninfo.secure ? "https" : "http") + "://" + coninfo.server + ":" + coninfo.portToUse + "/";
URL += parsed[2] + "/httpPassthrough";
if (isTeacher) {
URL += "?private";
}
var message = '<a href="' + URL + '" target="_blank">';
message += VPLUtil.str('open') + '</a>';
var options = {
width: 200,
icon: 'run',
title: VPLUtil.str('run'),
};
showMessage(message, options);
} else {
// ...
}
},
// ...
}
diff --git a/amd/src/vplide.js b/amd/src/vplide.js
index 586b5ff5..d1f88f47 100644
--- a/amd/src/vplide.js
+++ b/amd/src/vplide.js
@@ -2024,8 +2024,8 @@ define(
'setResult': self.setResult,
'ajaxurl': options.ajaxurl,
'run': function(content, coninfo, ws) {
- var parsed = /^([^:]*):?(.*)/i.exec(content);
- var type = parsed[1];
+ var parsed = /^([^:]*):?(.*)/.exec(content);
+ var type = VPLUtil.sanitizeText(parsed[1]);
if (type == 'terminal' || type == 'webterminal') {
if (lastConsole && lastConsole.isOpen()) {
lastConsole.close();
@@ -2055,7 +2055,7 @@ define(
});
} else if (type == "browser") {
var URL = (coninfo.secure ? "https" : "http") + "://" + coninfo.server + ":" + coninfo.portToUse + "/";
- URL += parsed[2] + "/httpPassthrough";
+ URL += VPLUtil.sanitizeText(parsed[2]) + "/httpPassthrough";
if (isTeacher) {
URL += "?private";
}
diff --git a/amd/src/vplui.js b/amd/src/vplui.js
index 36504a33..648472d6 100644
--- a/amd/src/vplui.js
+++ b/amd/src/vplui.js
@@ -582,8 +582,8 @@ define(
var messageActions = {
'message': function(content) {
var parsed = /^([^:]*):?([^]*)/.exec(content);
- var state = parsed[1];
- var detail = parsed[2];
+ var state = VPLUtil.sanitizeText(parsed[1]);
+ var detail = VPLUtil.sanitizeText(parsed[2]);
if (state == 'running') {
state = running;
}
@@ -607,7 +607,7 @@ define(
}
},
'retrieve': function() {
- var data = {"processid": VPLUtil.getProcessId()};
+ var data = {"processid": coninfo.processid};
pb.close();
delegated = true;
VPLUI.requestAction('retrieve', '', data, externalActions.ajaxurl)
@@ -627,7 +627,7 @@ define(
'close': function() {
VPLUtil.log('ws close message from jail');
ws.close();
- var data = {"processid": VPLUtil.getProcessId()};
+ var data = {"processid": coninfo.processid};
VPLUI.requestAction('cancel', '', data, externalActions.ajaxurl, true);
}
};