VYPR
Moderate severityNVD Advisory· Published Oct 7, 2024· Updated Mar 25, 2025

CVE-2024-28709

CVE-2024-28709

Description

Cross Site Scripting vulnerability in LimeSurvey before 6.5.12+240611 allows a remote attacker to execute arbitrary code via a crafted script to the title and comment fields.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Stored XSS in LimeSurvey before 6.5.12+240611 allows arbitrary JavaScript execution via crafted title/comment fields in file upload questions.

CVE-2024-28709 is a stored cross-site scripting (XSS) vulnerability in LimeSurvey, an open-source survey platform [2]. The flaw exists in the file upload question type, where the title and comment fields are not properly sanitized before being displayed. The root cause is the lack of HTML entity encoding on these inputs, allowing injection of arbitrary HTML and JavaScript. [4]

Exploitation requires an attacker to have the ability to edit survey questions or submit data that will be stored and later displayed. Users with survey editing privileges (such as administrators or authorized survey creators) can inject malicious scripts into the title or comment fields of file upload questions. When other users view the survey or its results, the stored payload executes in their browser.

Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the LimeSurvey application. This can lead to session hijacking, data theft, unauthorized actions performed on behalf of the victim, and defacement. The impact is significant given that LimeSurvey is used to collect sensitive data.

The vulnerability has been patched in LimeSurvey version 6.5.12+240611. The fix applies htmlentities() to the title and comment variables in the file upload question controller, as seen in the commit. [4] Users are advised to update immediately; no workarounds have been provided.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
limesurvey/limesurveyPackagist
< 6.5.126.5.12

Affected products

3

Patches

1
c844c4fba81c

Fixed issue #19457: [security] Stored Cross-Site Scripting (XSS) in file upload question (#3874)

https://github.com/LimeSurvey/LimeSurveyGabriel JenikJun 10, 2024via ghsa
4 files changed · +7 7
  • assets/packages/questions/upload/build/uploadquestion.js+3 3 modified
    @@ -783,8 +783,8 @@
                   imageOrPlaceholderHtml = '<div class="upload-placeholder"></div>';
                 }
     
    -            title = show_title != 0 ? item.title : '';
    -            comment = show_comment != 0 ? item.comment : '';
    +            title = show_title != 0 ? htmlentities(item.title) : '';
    +            comment = show_comment != 0 ? htmlentities(item.comment) : '';
                 name = item.name;
                 filepointer = iterator;
                 const rowHtml = this.replaceWithObject(templateHtml, {
    @@ -948,7 +948,7 @@
                 // you can disable upload button
     
                 this.disable();
    -            button.append('<i id="loading-icon-fielupload" class="fa fa-spinner fa-pulse fa-3x fa-fw ri-loader-fill remix-pulse ri-3x"></i>');
    +            button.append('<i id="loading-icon-fielupload" class="fa fa-spinner fa-pulse fa-3x fa-fw ri-loader-fill remix-pulse ri-3x" ></i>');
               },
               onComplete: function (file, response) {
                 button.text(uploadLang.selectfile);
    
  • assets/packages/questions/upload/build/uploadquestion.min.js+1 1 modified
    @@ -1,2 +1,2 @@
    -!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";(function(){function addEvent(e,t,a){if(e.addEventListener)e.addEventListener(t,a,!1);else{if(!e.attachEvent)throw new Error("not supported or DOM not loaded");e.attachEvent("on"+t,(function(){a.call(e)}))}}if(document.documentElement.getBoundingClientRect)var getOffset=function(e){var t=e.getBoundingClientRect(),a=e.ownerDocument,i=a.body,l=a.documentElement,n=l.clientTop||i.clientTop||0,s=l.clientLeft||i.clientLeft||0,o=1;if(i.getBoundingClientRect){var r=i.getBoundingClientRect();o=(r.right-r.left)/i.clientWidth}return o>1&&(n=0,s=0),{top:t.top/o+(window.pageYOffset||l&&l.scrollTop/o||i.scrollTop/o)-n,left:t.left/o+(window.pageXOffset||l&&l.scrollLeft/o||i.scrollLeft/o)-s}};else var getOffset=function(e){var t=0,a=0;do{t+=e.offsetTop||0,a+=e.offsetLeft||0,e=e.offsetParent}while(e);return{left:a,top:t}};function getBox(e){var t,a,i=getOffset(e);return t=i.left,a=i.top,{left:t,right:t+e.offsetWidth,top:a,bottom:a+e.offsetHeight}}function addStyles(e,t){for(var a in t)t.hasOwnProperty(a)&&(e.style[a]=t[a])}function copyLayout(e,t){var a=getBox(e);addStyles(t,{position:"absolute",left:a.left+"px",top:a.top+"px",width:e.offsetWidth+"px",height:e.offsetHeight+"px"})}var toElement=(div=document.createElement("div"),function(e){div.innerHTML=e;var t=div.firstChild;return div.removeChild(t)}),div,getUID=(id=0,function(){return"ValumsAjaxUpload"+id++}),id;function fileFromPath(e){return e.replace(/.*(\/|\\)/,"")}function getExt(e){return-1!==(e=e.toLowerCase()).indexOf(".")?e.replace(/.*[.]/,""):""}function hasClass(e,t){return new RegExp("\\b"+t+"\\b").test(e.className)}function addClass(e,t){hasClass(e,t)||(e.className+=" "+t)}function removeClass(e,t){var a=new RegExp("\\b"+t+"\\b");e.className=e.className.replace(a,"")}function removeNode(e){e.parentNode.removeChild(e)}window.AjaxUpload=function(e,t){for(var a in this._settings={action:"upload.php",name:"userfile",multiple:!1,data:{},autoSubmit:!0,responseType:!1,hoverClass:"hover",focusClass:"focus",disabledClass:"disabled",onChange:function(e,t){},onSubmit:function(e,t){},onComplete:function(e,t){}},t)t.hasOwnProperty(a)&&(this._settings[a]=t[a]);if(e.jquery?e=e[0]:"string"==typeof e&&(/^#.*/.test(e)&&(e=e.slice(1)),e=document.getElementById(e)),!e||1!==e.nodeType)throw new Error("Please make sure that you're passing a valid element");"A"==e.nodeName.toUpperCase()&&addEvent(e,"click",(function(e){e&&e.preventDefault?e.preventDefault():window.event&&(window.event.returnValue=!1)})),this._button=e,this._input=null,this._disabled=!1,this.enable(),this._rerouteClicks()},AjaxUpload.prototype={setData:function(e){this._settings.data=e},disable:function(){addClass(this._button,this._settings.disabledClass),this._disabled=!0;var e=this._button.nodeName.toUpperCase();"INPUT"!=e&&"BUTTON"!=e||this._button.setAttribute("disabled","disabled"),this._input&&this._input.parentNode&&(this._input.parentNode.style.visibility="hidden")},enable:function(){removeClass(this._button,this._settings.disabledClass),this._button.removeAttribute("disabled"),this._disabled=!1},_createInput:function(){var e=this,t=document.createElement("input");t.setAttribute("type","file"),t.setAttribute("name",this._settings.name),this._settings.multiple&&t.setAttribute("multiple","multiple"),addStyles(t,{position:"absolute",right:0,margin:0,padding:0,fontSize:"480px",fontFamily:"sans-serif",cursor:"pointer"});var a=document.createElement("div");if(addStyles(a,{display:"block",position:"absolute",overflow:"hidden",margin:0,padding:0,opacity:0,direction:"ltr",zIndex:2147483583}),"0"!==a.style.opacity){if(void 0===a.filters)throw new Error("Opacity not supported by the browser");a.style.filter="alpha(opacity=0)"}addEvent(t,"change",(function(){if(t&&""!==t.value){var a=fileFromPath(t.value);!1!==e._settings.onChange.call(e,a,getExt(a))?e._settings.autoSubmit&&e.submit():e._clearInput()}})),addEvent(t,"mouseover",(function(){addClass(e._button,e._settings.hoverClass)})),addEvent(t,"mouseout",(function(){removeClass(e._button,e._settings.hoverClass),removeClass(e._button,e._settings.focusClass),t.parentNode&&(t.parentNode.style.visibility="hidden")})),addEvent(t,"focus",(function(){addClass(e._button,e._settings.focusClass)})),addEvent(t,"blur",(function(){removeClass(e._button,e._settings.focusClass)})),a.appendChild(t),document.body.appendChild(a),this._input=t},_clearInput:function(){this._input&&(removeNode(this._input.parentNode),this._input=null,this._createInput(),removeClass(this._button,this._settings.hoverClass),removeClass(this._button,this._settings.focusClass))},_rerouteClicks:function(){var e=this;addEvent(e._button,"mouseover",(function(){if(!e._disabled){e._input||e._createInput();var t=e._input.parentNode;copyLayout(e._button,t),t.style.visibility="visible"}}))},_createIframe:function(){var e=getUID(),t=toElement('<iframe src="javascript:false;" name="'+e+'" />');return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t},_createForm:function(e){var t=this._settings,a=toElement('<form method="post" enctype="multipart/form-data"></form>');for(var i in a.setAttribute("action",t.action),a.setAttribute("target",e.name),a.style.display="none",document.body.appendChild(a),t.data)if(t.data.hasOwnProperty(i)){var l=document.createElement("input");l.setAttribute("type","hidden"),l.setAttribute("name",i),l.setAttribute("value",t.data[i]),a.appendChild(l)}return a},_getResponse:function(iframe,file){var toDeleteFlag=!1,self=this,settings=this._settings;addEvent(iframe,"load",(function(){if("javascript:'%3CHtml%3E%3C/html%3E';"!=iframe.src&&"javascript:'<html></html>';"!=iframe.src){var doc=iframe.contentDocument?iframe.contentDocument:window.frames[iframe.id].document,response;if(!doc.readyState||"complete"==doc.readyState)if(!doc.body||"false"!=doc.body.innerHTML)doc.XMLDocument?response=doc.XMLDocument:doc.body?(response=doc.body.innerHTML,settings.responseType&&"json"==settings.responseType.toLowerCase()&&(doc.body.firstChild&&"PRE"==doc.body.firstChild.nodeName.toUpperCase()&&(doc.normalize(),response=doc.body.firstChild.firstChild.nodeValue),response=response?eval("("+response+")"):{})):response=doc,settings.onComplete.call(self,file,response),toDeleteFlag=!0,iframe.src="javascript:'<html></html>';",removeNode(iframe)}else toDeleteFlag&&setTimeout((function(){removeNode(iframe)}),0)}))},submit:function(){var e=this,t=this._settings;if(this._input&&""!==this._input.value){var a=fileFromPath(this._input.value);if(!1!==t.onSubmit.call(this,a,getExt(a))){var i=this._createIframe();this._getResponse(i,a);var l=this._createForm(i);removeNode(this._input.parentNode),removeClass(e._button,e._settings.hoverClass),removeClass(e._button,e._settings.focusClass),l.appendChild(this._input),l.submit(),removeNode(l),l=null,removeNode(this._input),this._input=null,this._createInput()}else this._clearInput()}}}})(),window.uploadModalObjects=window.uploadModalObjects||{};class UploadQuestionController{constructor(e){this.fieldname=e,this.$el=$("#upload_"+e),this.$modalEl=$("#file-upload-modal-"+this.fieldname),this.show_title=this.$el.data("showtitle"),this.show_comment=this.$el.data("showcomment")}prepareOpenUploadModalDialog(){({})[uploadLang.returnTxt]=()=>{this.$el.dialog("close")},$(document).off("shown.bs.modal.lsuploadquestion","#file-upload-modal-"+this.fieldname),$(document).on("shown.bs.modal.lsuploadquestion","#file-upload-modal-"+this.fieldname,(()=>{const e=$("#uploader"+this.fieldname);e.load(e.data("src")),this.updateMaxHeightModalbody(this.$el)})),this.$modalEl.off("hide.bs.modal.lsuploadquestion"),this.$modalEl.on("hide.bs.modal.lsuploadquestion",(()=>{const e=$("#uploader"+this.fieldname);return window.currentUploadHandler.saveAndExit(this.fieldname,this.show_title,this.show_comment,1),e.html(""),!0})),this.$el.off("click.lsuploadquestion"),this.$el.on("click.lsuploadquestion",(e=>{console.ls.log("File upload modal opening"),this.$modalEl.modal("show")}))}updateUploadFrame(e,t){$("#"+e).innerHeight(t)}updateMaxHeightModalbody(e){const t=$(e).find(".modal-header").outerHeight(),a=$(e).find(".modal-footer").outerHeight(),i=Math.max(150,$(window).height()-(t+a+16));console.ls.log([$(window).height(),t,a,t+a]),$(e).find(".modal-body").css("max-height",i)}getQueryVariable(e,t){const a=t.split("/");for(let t=0;t<a.length;t++)if(a[t]==e)return a[t+1];const i=t.replace(/\&amp;/g,"&").split("&");for(let t=0;t<vars.length;t++){const a=i[t].split("=");if(a[0]==e)return a[1]}return null}isValueInArray(e,t){inArray=!1;for(let a=0;a<e.length;a++)t.toLowerCase()==e[a].toLowerCase()&&(inArray=!0);return inArray}displayUploadedFiles(e,t,a,i){const l=$("#java"+t).val();if("[]"==l||""==l)return $("#"+this.fieldname+"_uploadedfiles").addClass("d-none"),void $("#"+this.fieldname+"_uploadedfiles").find("table>tbody").html("");if(""!==l){let e=[];try{e=JSON.parse(l)}catch(e){}$("#"+this.fieldname+"_uploadedfiles").removeClass("d-none"),$("#"+this.fieldname+"_uploadedfiles").find("table>tbody").html("");const t=new Array("gif","jpeg","jpg","png","swf","psd","bmp","tiff","jp2","iff","bmp","xbm","ico"),n=$("#filerowtemplate_"+this.fieldname).html();e.forEach(((e,l)=>{let s,o,r,d,p,u;this.isValueInArray(t,e.ext)?(s="image",o='<img src="'+uploadurl+"/filegetcontents/"+decodeURIComponent(e.filename)+'" class="uploaded" />'):(s="placeholder",o='<div class="upload-placeholder"></div>'),r=0!=a?e.title:"",d=0!=i?e.comment:"",p=e.name,u=l;const c=this.replaceWithObject(n,{imageOrPlaceholder:s,imageOrPlaceholderHtml:o,title:r,comment:d,name:p,filepointer:u});$("#"+this.fieldname+"_uploadedfiles").find("table>tbody").append(c)})),$(".trigger_edit_upload_"+this.fieldname).off("click.lsuploadquestion"),$(".trigger_edit_upload_"+this.fieldname).on("click.lsuploadquestion",(()=>{this.$modalEl.modal("show")}))}}replaceWithObject(e,t){let a=e;for(let e in t)a=a.replace(new RegExp(`{${e}}`),t[e]);return a}showBasic(){$("#basic").show()}hideBasic(){$("#basic").hide()}}window.UploadQuestionController=UploadQuestionController;var uploadHandler=function(e,t){var a=function(e,a,i){var l,n,o=i,r=new Array("gif","jpeg","jpg","png","swf","psd","bmp","tiff","jp2","iff","bmp","xbm","ico","heic"),d=$('<li id="'+e+"_li_"+o+'" class="previewblock file-element"></li>'),p=$('<div class="file-preview"></div>');if(l=r,n=a.ext.toLowerCase(),l.reduce((function(e,t){return e||n.toLowerCase()==t.toLowerCase()}),!1)?p.append('<img src="'+t.uploadurl+"/filegetcontents/"+a.filename+'" class="uploaded" />'):p.append('<div class="upload-placeholder"></div>'),p.append('<span class="file-name">'+escapeHtml(a.name)+"</span>"),1==$("#"+e+"_show_title").val()||1==$("#"+e+"_show_comment").val()){var u=$(""),c=$("");if(1==$("#"+e+"_show_title").val()){u=$('<div class="mb-3"></div>');$('<label class="control-label col-5"></label>').attr("for",e+"_title_"+o).text(t.uploadLang.titleFld).appendTo(u),$('<input class="form-control" type="text"/>').attr("id",e+"_title_"+o).val(a.title).wrap('<div class="input-container"></div>').appendTo(u)}if(1==$("#"+e+"_show_comment").val()){c=$('<div class="mb-3"></div>');$('<label class="control-label col-5"></label>').attr("for",e+"_comment_"+o).text(t.uploadLang.commentFld).appendTo(c),$('<input class="form-control" type="text"/>').attr("id",e+"_comment_"+o).val(a.comment).wrap('<div class="input-container"></div>').appendTo(c)}}var f=$('<div class="mb-3"></div>').append($('<a class="btn btn-danger"></a>').html('<span class="fa fa-trash"></span>&nbsp;'+t.uploadLang.deleteFile).on("click",(function(){s(e,o)})).wrap('<div class="input-container text-center"></div>'));$("<fieldset></fieldset>").append(u).append(c).append(f).wrap('<div class="file-info"></div>').appendTo(p),$('<input type="hidden" />').attr("id",e+"_size_"+o).attr("value",a.size).appendTo(d),$('<input type="hidden" />').attr("id",e+"_name_"+o).attr("value",a.name).appendTo(d),$('<input type="hidden" />').attr("id",e+"_file_index_"+o).attr("value",o).appendTo(d),$('<input type="hidden" />').attr("id",e+"_filename_"+o).attr("value",a.filename).appendTo(d),$('<input type="hidden" />').attr("id",e+"_ext_"+o).attr("value",a.ext).appendTo(d),0===$("#"+e+"_li_"+o).length&&(d.append(p),$("#field"+e+"_listfiles").append(d))},i=function(){var i=t.sFieldName,l=$("#java"+i+"_filecount").val();if($("#java"+i+"_filecount").val(l),l>0){var n=$("#java"+i).val(),s="";try{s=JSON.parse(n)}catch(e){}0==$("#field"+i+"_listfiles").length&&$('<ul id="field'+i+'_listfiles" class="files-list" />').insertAfter("#uploadstatus_"+e),$("#"+i+"_licount").val(l),s.forEach((function(e,t){a(i,e,t+1)}))}var o=$("#button_"+e);new AjaxUpload(o,{action:t.uploadurl+"/sid/"+surveyid+"/preview/"+t.questgrppreview+"/fieldname/"+i+"/",name:"uploadfile",data:{valid_extensions:$("#"+i+"_allowed_filetypes").val(),max_filesize:$("#"+i+"_maxfilesize").val(),preview:$("#preview").val(),surveyid:surveyid,fieldname:i,YII_CSRF_TOKEN:t.csrfToken},onSubmit:function(e,a){var l=parseInt($("#"+i+"_maxfiles").val()),n=parseInt($("#java"+i+"_filecount").val()),s=$("#"+i+"_allowed_filetypes").val().split(",");if(n>=l)return $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle"></span>&nbsp;'+uploadLang.errorNoMoreFiles+"</p>"),!1;let r=!1;for(let e of s)r=s.includes(e);if(0==r)return $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle"></span>&nbsp;'+uploadLang.errorOnlyAllowed.replace("%s",$("#"+i+"_allowed_filetypes").val())+"</p>"),!1;o.text(t.uploadLang.uploading),this.disable(),o.append('<i id="loading-icon-fielupload" class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>')},onComplete:function(e,l){o.text(uploadLang.selectfile),$("#loading-icon-fielupload").remove(),this.enable();try{var n=JSON.parse(l)}catch(e){return void $("body").html(l)}var s=parseInt($("#"+i+"_licount").val());if(s++,$("#"+i+"_licount").val(s),n.success){$("#notice").html('<p class="alert alert-success"><span class="fa fa-success"></span>&nbsp;'+n.msg+"</p>"),0==$("#field"+i+"_listfiles").length&&$("<ul id='field"+i+"_listfiles' class='files-list' />").insertAfter("#uploadstatus_"+t.qid),a(i,n,s);var r=parseInt($("#java"+i+"_filecount").val()),d=parseInt($("#"+i+"_minfiles").val());r++;var p=parseInt($("#"+i+"_maxfiles").val());$("#java"+i+"_filecount").val(r),r<d?$("#uploadstatus").html(t.uploadLang.errorNeedMore.replace("%s",d-r)):r<p?$("#uploadstatus").html(t.uploadLang.errorMoreAllowed.replace("%s",p-r)):$("#uploadstatus").html(t.uploadLang.errorMaxReached),r>=p&&$("#notice").html('<p class="alert alert-success"><span class="fa fa-check"></span>&nbsp;'+t.uploadLang.errorTooMuch+"</p>")}else $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle"></span>&nbsp;'+n.msg+"</p>")}})};function l(e,t,a,i){for(var l=[],s=0,o=parseInt($("#"+e+"_licount").val()),r=1;r<=o;){if($("#"+e+"_li_"+r).is(":visible")){var d={title:1==$("#"+e+"_show_title").val()?$("#"+e+"_title_"+r).val():"",comment:1==$("#"+e+"_show_comment").val()?$("#"+e+"_comment_"+r).val():"",size:$("#"+e+"_size_"+r).val(),name:$("#"+e+"_name_"+r).val(),filename:$("#"+e+"_filename_"+r).val(),ext:$("#"+e+"_ext_"+r).val()};s+=1,l.push(d)}r++}$("#java"+e).val(JSON.stringify(l)).trigger("updated"),n(s,e,t,a,i)}const n=function(e,t,a,i,l){$("#java"+t+"_filecount").val(e).trigger("updated"),window["uploadQuestionController_"+t].displayUploadedFiles(e,t,a,i,l)};var s=function(e,a){var i,l=$("#"+e+"_filename_"+a).val(),n=$("#"+e+"_name_"+a).val(),s=parseInt($("#java"+e+"_filecount").val()),o=parseInt($("#"+e+"_licount").val());$.ajax({method:"POST",url:uploadurl,data:{delete:1,fieldname:e,filename:l,name:n,YII_CSRF_TOKEN:t.csrfToken}}).done((function(t){for($("#notice").html('<p class="alert alert-success"><span class="fa fa-check"></span>&nbsp;'+t+"</p>"),setTimeout((function(){$(".success").remove()}),5e3),$("#"+e+"_li_"+a).hide(),s--,$("#java"+e+"_filecount").val(s),i=$("#"+e+"_file_index_"+a).val(),j=a;j<=o;j++)$("#"+e+"_li_"+j).is(":visible")&&($("#"+e+"_file_index_"+j).val(i),i++);var l=parseInt($("#"+e+"_minfiles").val()),n=parseInt($("#"+e+"_maxfiles").val());s<l?$("#uploadstatus").html(uploadLang.errorNeedMore.replace("%s",l-s)):$("#uploadstatus").html(uploadLang.errorMoreAllowed.replace("%s",n-s))}))};return{init:function(){i()},saveAndExit:function(e,t,a,i){var n=parseInt($("#java"+e+"_filecount").val()),s=parseInt($("#"+e+"_minfiles").val());return 0!=s&&n<s&&showpopups?!!confirm(uploadLang.errorNeedMoreConfirm.replace("%s",s-n))&&(l(e,t,a,i),!0):(l(e,t,a,i),!0)}}};function escapeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}window.getUploadHandler=function(e,t){return window.currentUploadHandler=new uploadHandler(e,t),window.currentUploadHandler.init(),window.currentUploadHandler}}));
    +!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";(function(){function addEvent(e,t,a){if(e.addEventListener)e.addEventListener(t,a,!1);else{if(!e.attachEvent)throw new Error("not supported or DOM not loaded");e.attachEvent("on"+t,(function(){a.call(e)}))}}if(document.documentElement.getBoundingClientRect)var getOffset=function(e){var t=e.getBoundingClientRect(),a=e.ownerDocument,i=a.body,l=a.documentElement,n=l.clientTop||i.clientTop||0,s=l.clientLeft||i.clientLeft||0,o=1;if(i.getBoundingClientRect){var r=i.getBoundingClientRect();o=(r.right-r.left)/i.clientWidth}return o>1&&(n=0,s=0),{top:t.top/o+(window.pageYOffset||l&&l.scrollTop/o||i.scrollTop/o)-n,left:t.left/o+(window.pageXOffset||l&&l.scrollLeft/o||i.scrollLeft/o)-s}};else var getOffset=function(e){var t=0,a=0;do{t+=e.offsetTop||0,a+=e.offsetLeft||0,e=e.offsetParent}while(e);return{left:a,top:t}};function getBox(e){var t,a,i=getOffset(e);return t=i.left,a=i.top,{left:t,right:t+e.offsetWidth,top:a,bottom:a+e.offsetHeight}}function addStyles(e,t){for(var a in t)t.hasOwnProperty(a)&&(e.style[a]=t[a])}function copyLayout(e,t){var a=getBox(e);addStyles(t,{position:"absolute",left:a.left+"px",top:a.top+"px",width:e.offsetWidth+"px",height:e.offsetHeight+"px"})}var toElement=(div=document.createElement("div"),function(e){div.innerHTML=e;var t=div.firstChild;return div.removeChild(t)}),div,getUID=(id=0,function(){return"ValumsAjaxUpload"+id++}),id;function fileFromPath(e){return e.replace(/.*(\/|\\)/,"")}function getExt(e){return-1!==(e=e.toLowerCase()).indexOf(".")?e.replace(/.*[.]/,""):""}function hasClass(e,t){return new RegExp("\\b"+t+"\\b").test(e.className)}function addClass(e,t){hasClass(e,t)||(e.className+=" "+t)}function removeClass(e,t){var a=new RegExp("\\b"+t+"\\b");e.className=e.className.replace(a,"")}function removeNode(e){e.parentNode.removeChild(e)}window.AjaxUpload=function(e,t){for(var a in this._settings={action:"upload.php",name:"userfile",multiple:!1,data:{},autoSubmit:!0,responseType:!1,hoverClass:"hover",focusClass:"focus",disabledClass:"disabled",onChange:function(e,t){},onSubmit:function(e,t){},onComplete:function(e,t){}},t)t.hasOwnProperty(a)&&(this._settings[a]=t[a]);if(e.jquery?e=e[0]:"string"==typeof e&&(/^#.*/.test(e)&&(e=e.slice(1)),e=document.getElementById(e)),!e||1!==e.nodeType)throw new Error("Please make sure that you're passing a valid element");"A"==e.nodeName.toUpperCase()&&addEvent(e,"click",(function(e){e&&e.preventDefault?e.preventDefault():window.event&&(window.event.returnValue=!1)})),this._button=e,this._input=null,this._disabled=!1,this.enable(),this._rerouteClicks()},AjaxUpload.prototype={setData:function(e){this._settings.data=e},disable:function(){addClass(this._button,this._settings.disabledClass),this._disabled=!0;var e=this._button.nodeName.toUpperCase();"INPUT"!=e&&"BUTTON"!=e||this._button.setAttribute("disabled","disabled"),this._input&&this._input.parentNode&&(this._input.parentNode.style.visibility="hidden")},enable:function(){removeClass(this._button,this._settings.disabledClass),this._button.removeAttribute("disabled"),this._disabled=!1},_createInput:function(){var e=this,t=document.createElement("input");t.setAttribute("type","file"),t.setAttribute("name",this._settings.name),this._settings.multiple&&t.setAttribute("multiple","multiple"),addStyles(t,{position:"absolute",right:0,margin:0,padding:0,fontSize:"480px",fontFamily:"sans-serif",cursor:"pointer"});var a=document.createElement("div");if(addStyles(a,{display:"block",position:"absolute",overflow:"hidden",margin:0,padding:0,opacity:0,direction:"ltr",zIndex:2147483583}),"0"!==a.style.opacity){if(void 0===a.filters)throw new Error("Opacity not supported by the browser");a.style.filter="alpha(opacity=0)"}addEvent(t,"change",(function(){if(t&&""!==t.value){var a=fileFromPath(t.value);!1!==e._settings.onChange.call(e,a,getExt(a))?e._settings.autoSubmit&&e.submit():e._clearInput()}})),addEvent(t,"mouseover",(function(){addClass(e._button,e._settings.hoverClass)})),addEvent(t,"mouseout",(function(){removeClass(e._button,e._settings.hoverClass),removeClass(e._button,e._settings.focusClass),t.parentNode&&(t.parentNode.style.visibility="hidden")})),addEvent(t,"focus",(function(){addClass(e._button,e._settings.focusClass)})),addEvent(t,"blur",(function(){removeClass(e._button,e._settings.focusClass)})),a.appendChild(t),document.body.appendChild(a),this._input=t},_clearInput:function(){this._input&&(removeNode(this._input.parentNode),this._input=null,this._createInput(),removeClass(this._button,this._settings.hoverClass),removeClass(this._button,this._settings.focusClass))},_rerouteClicks:function(){var e=this;addEvent(e._button,"mouseover",(function(){if(!e._disabled){e._input||e._createInput();var t=e._input.parentNode;copyLayout(e._button,t),t.style.visibility="visible"}}))},_createIframe:function(){var e=getUID(),t=toElement('<iframe src="javascript:false;" name="'+e+'" />');return t.setAttribute("id",e),t.style.display="none",document.body.appendChild(t),t},_createForm:function(e){var t=this._settings,a=toElement('<form method="post" enctype="multipart/form-data"></form>');for(var i in a.setAttribute("action",t.action),a.setAttribute("target",e.name),a.style.display="none",document.body.appendChild(a),t.data)if(t.data.hasOwnProperty(i)){var l=document.createElement("input");l.setAttribute("type","hidden"),l.setAttribute("name",i),l.setAttribute("value",t.data[i]),a.appendChild(l)}return a},_getResponse:function(iframe,file){var toDeleteFlag=!1,self=this,settings=this._settings;addEvent(iframe,"load",(function(){if("javascript:'%3CHtml%3E%3C/html%3E';"!=iframe.src&&"javascript:'<html></html>';"!=iframe.src){var doc=iframe.contentDocument?iframe.contentDocument:window.frames[iframe.id].document,response;if(!doc.readyState||"complete"==doc.readyState)if(!doc.body||"false"!=doc.body.innerHTML)doc.XMLDocument?response=doc.XMLDocument:doc.body?(response=doc.body.innerHTML,settings.responseType&&"json"==settings.responseType.toLowerCase()&&(doc.body.firstChild&&"PRE"==doc.body.firstChild.nodeName.toUpperCase()&&(doc.normalize(),response=doc.body.firstChild.firstChild.nodeValue),response=response?eval("("+response+")"):{})):response=doc,settings.onComplete.call(self,file,response),toDeleteFlag=!0,iframe.src="javascript:'<html></html>';",removeNode(iframe)}else toDeleteFlag&&setTimeout((function(){removeNode(iframe)}),0)}))},submit:function(){var e=this,t=this._settings;if(this._input&&""!==this._input.value){var a=fileFromPath(this._input.value);if(!1!==t.onSubmit.call(this,a,getExt(a))){var i=this._createIframe();this._getResponse(i,a);var l=this._createForm(i);removeNode(this._input.parentNode),removeClass(e._button,e._settings.hoverClass),removeClass(e._button,e._settings.focusClass),l.appendChild(this._input),l.submit(),removeNode(l),l=null,removeNode(this._input),this._input=null,this._createInput()}else this._clearInput()}}}})(),window.uploadModalObjects=window.uploadModalObjects||{};class UploadQuestionController{constructor(e){this.fieldname=e,this.$el=$("#upload_"+e),this.$modalEl=$("#file-upload-modal-"+this.fieldname),this.show_title=this.$el.data("showtitle"),this.show_comment=this.$el.data("showcomment")}prepareOpenUploadModalDialog(){({})[uploadLang.returnTxt]=()=>{this.$el.dialog("close")},$(document).off("shown.bs.modal.lsuploadquestion","#file-upload-modal-"+this.fieldname),$(document).on("shown.bs.modal.lsuploadquestion","#file-upload-modal-"+this.fieldname,(()=>{const e=$("#uploader"+this.fieldname);e.load(e.data("src")),this.updateMaxHeightModalbody(this.$el)})),this.$modalEl.off("hide.bs.modal.lsuploadquestion"),this.$modalEl.on("hide.bs.modal.lsuploadquestion",(()=>{const e=$("#uploader"+this.fieldname);return window.currentUploadHandler.saveAndExit(this.fieldname,this.show_title,this.show_comment,1),e.html(""),!0})),this.$el.off("click.lsuploadquestion"),this.$el.on("click.lsuploadquestion",(e=>{console.ls.log("File upload modal opening"),this.$modalEl.modal("show")}))}updateUploadFrame(e,t){$("#"+e).innerHeight(t)}updateMaxHeightModalbody(e){const t=$(e).find(".modal-header").outerHeight(),a=$(e).find(".modal-footer").outerHeight(),i=Math.max(150,$(window).height()-(t+a+16));console.ls.log([$(window).height(),t,a,t+a]),$(e).find(".modal-body").css("max-height",i)}getQueryVariable(e,t){const a=t.split("/");for(let t=0;t<a.length;t++)if(a[t]==e)return a[t+1];const i=t.replace(/\&amp;/g,"&").split("&");for(let t=0;t<vars.length;t++){const a=i[t].split("=");if(a[0]==e)return a[1]}return null}isValueInArray(e,t){inArray=!1;for(let a=0;a<e.length;a++)t.toLowerCase()==e[a].toLowerCase()&&(inArray=!0);return inArray}displayUploadedFiles(e,t,a,i){const l=$("#java"+t).val();if("[]"==l||""==l)return $("#"+this.fieldname+"_uploadedfiles").addClass("d-none"),void $("#"+this.fieldname+"_uploadedfiles").find("table>tbody").html("");if(""!==l){let e=[];try{e=JSON.parse(l)}catch(e){}$("#"+this.fieldname+"_uploadedfiles").removeClass("d-none"),$("#"+this.fieldname+"_uploadedfiles").find("table>tbody").html("");const t=new Array("gif","jpeg","jpg","png","swf","psd","bmp","tiff","jp2","iff","bmp","xbm","ico"),n=$("#filerowtemplate_"+this.fieldname).html();e.forEach(((e,l)=>{let s,o,r,d,p,u;this.isValueInArray(t,e.ext)?(s="image",o='<img src="'+uploadurl+"/filegetcontents/"+decodeURIComponent(e.filename)+'" class="uploaded" />'):(s="placeholder",o='<div class="upload-placeholder"></div>'),r=0!=a?htmlentities(e.title):"",d=0!=i?htmlentities(e.comment):"",p=e.name,u=l;const c=this.replaceWithObject(n,{imageOrPlaceholder:s,imageOrPlaceholderHtml:o,title:r,comment:d,name:p,filepointer:u});$("#"+this.fieldname+"_uploadedfiles").find("table>tbody").append(c)})),$(".trigger_edit_upload_"+this.fieldname).off("click.lsuploadquestion"),$(".trigger_edit_upload_"+this.fieldname).on("click.lsuploadquestion",(()=>{this.$modalEl.modal("show")}))}}replaceWithObject(e,t){let a=e;for(let e in t)a=a.replace(new RegExp(`{${e}}`),t[e]);return a}showBasic(){$("#basic").show()}hideBasic(){$("#basic").hide()}}window.UploadQuestionController=UploadQuestionController;var uploadHandler=function(e,t){var a=function(e,a,i){var l,n,o=i,r=new Array("gif","jpeg","jpg","png","swf","psd","bmp","tiff","jp2","iff","bmp","xbm","ico","heic"),d=$('<li id="'+e+"_li_"+o+'" class="previewblock file-element"></li>'),p=$('<div class="file-preview"></div>');if(l=r,n=a.ext.toLowerCase(),l.reduce((function(e,t){return e||n.toLowerCase()==t.toLowerCase()}),!1)?p.append('<img src="'+t.uploadurl+"/filegetcontents/"+a.filename+'" class="uploaded" />'):p.append('<div class="upload-placeholder"></div>'),p.append('<span class="file-name">'+escapeHtml(a.name)+"</span>"),1==$("#"+e+"_show_title").val()||1==$("#"+e+"_show_comment").val()){var u=$(""),c=$("");if(1==$("#"+e+"_show_title").val()){u=$('<div class="mb-3"></div>');$('<label class="control-label col-5"></label>').attr("for",e+"_title_"+o).text(t.uploadLang.titleFld).appendTo(u),$('<input class="form-control" type="text"/>').attr("id",e+"_title_"+o).val(a.title).wrap('<div class="input-container"></div>').appendTo(u)}if(1==$("#"+e+"_show_comment").val()){c=$('<div class="mb-3"></div>');$('<label class="control-label col-5"></label>').attr("for",e+"_comment_"+o).text(t.uploadLang.commentFld).appendTo(c),$('<input class="form-control" type="text"/>').attr("id",e+"_comment_"+o).val(a.comment).wrap('<div class="input-container"></div>').appendTo(c)}}var f=$('<div class="mb-3"></div>').append($('<a class="btn btn-danger"></a>').html('<span class="fa fa-trash ri-delete-bin-fill"></span>&nbsp;'+t.uploadLang.deleteFile).on("click",(function(){s(e,o)})).wrap('<div class="input-container text-center"></div>'));$("<fieldset></fieldset>").append(u).append(c).append(f).wrap('<div class="file-info"></div>').appendTo(p),$('<input type="hidden" />').attr("id",e+"_size_"+o).attr("value",a.size).appendTo(d),$('<input type="hidden" />').attr("id",e+"_name_"+o).attr("value",a.name).appendTo(d),$('<input type="hidden" />').attr("id",e+"_file_index_"+o).attr("value",o).appendTo(d),$('<input type="hidden" />').attr("id",e+"_filename_"+o).attr("value",a.filename).appendTo(d),$('<input type="hidden" />').attr("id",e+"_ext_"+o).attr("value",a.ext).appendTo(d),0===$("#"+e+"_li_"+o).length&&(d.append(p),$("#field"+e+"_listfiles").append(d))},i=function(){var i=t.sFieldName,l=$("#java"+i+"_filecount").val();if($("#java"+i+"_filecount").val(l),l>0){var n=$("#java"+i).val(),s="";try{s=JSON.parse(n)}catch(e){}0==$("#field"+i+"_listfiles").length&&$('<ul id="field'+i+'_listfiles" class="files-list" />').insertAfter("#uploadstatus_"+e),$("#"+i+"_licount").val(l),s.forEach((function(e,t){a(i,e,t+1)}))}var o=$("#button_"+e);new AjaxUpload(o,{action:t.uploadurl+"/sid/"+surveyid+"/preview/"+t.questgrppreview+"/fieldname/"+i+"/",name:"uploadfile",data:{valid_extensions:$("#"+i+"_allowed_filetypes").val(),max_filesize:$("#"+i+"_maxfilesize").val(),preview:$("#preview").val(),surveyid:surveyid,fieldname:i,YII_CSRF_TOKEN:t.csrfToken},onSubmit:function(e,a){var l=parseInt($("#"+i+"_maxfiles").val()),n=parseInt($("#java"+i+"_filecount").val()),s=$("#"+i+"_allowed_filetypes").val().split(",");if(n>=l)return $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle ri-error-warning-fill"></span>&nbsp;'+uploadLang.errorNoMoreFiles+"</p>"),!1;let r=!1;for(let e of s)r=s.includes(e);if(0==r)return $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle ri-error-warning-fill"></span>&nbsp;'+uploadLang.errorOnlyAllowed.replace("%s",$("#"+i+"_allowed_filetypes").val())+"</p>"),!1;o.text(t.uploadLang.uploading),this.disable(),o.append('<i id="loading-icon-fielupload" class="fa fa-spinner fa-pulse fa-3x fa-fw ri-loader-fill remix-pulse ri-3x" ></i>')},onComplete:function(e,l){o.text(uploadLang.selectfile),$("#loading-icon-fielupload").remove(),this.enable();try{var n=JSON.parse(l)}catch(e){return void $("body").html(l)}var s=parseInt($("#"+i+"_licount").val());if(s++,$("#"+i+"_licount").val(s),n.success){$("#notice").html('<p class="alert alert-success"><span class="fa fa-check ri-check-fill"></span>&nbsp;'+n.msg+"</p>"),0==$("#field"+i+"_listfiles").length&&$("<ul id='field"+i+"_listfiles' class='files-list' />").insertAfter("#uploadstatus_"+t.qid),a(i,n,s);var r=parseInt($("#java"+i+"_filecount").val()),d=parseInt($("#"+i+"_minfiles").val());r++;var p=parseInt($("#"+i+"_maxfiles").val());$("#java"+i+"_filecount").val(r),r<d?$("#uploadstatus").html(t.uploadLang.errorNeedMore.replace("%s",d-r)):r<p?$("#uploadstatus").html(t.uploadLang.errorMoreAllowed.replace("%s",p-r)):$("#uploadstatus").html(t.uploadLang.errorMaxReached),r>=p&&$("#notice").html('<p class="alert alert-success"><span class="fa fa-check ri-check-fill"></span>&nbsp;'+t.uploadLang.errorTooMuch+"</p>")}else $("#notice").html('<p class="alert alert-danger"><span class="fa fa-exclamation-circle ri-error-warning-fill"></span>&nbsp;'+n.msg+"</p>")}})};function l(e,t,a,i){for(var l=[],s=0,o=parseInt($("#"+e+"_licount").val()),r=1;r<=o;){if($("#"+e+"_li_"+r).is(":visible")){var d={title:1==$("#"+e+"_show_title").val()?$("#"+e+"_title_"+r).val():"",comment:1==$("#"+e+"_show_comment").val()?$("#"+e+"_comment_"+r).val():"",size:$("#"+e+"_size_"+r).val(),name:$("#"+e+"_name_"+r).val(),filename:$("#"+e+"_filename_"+r).val(),ext:$("#"+e+"_ext_"+r).val()};s+=1,l.push(d)}r++}$("#java"+e).val(JSON.stringify(l)).trigger("updated"),n(s,e,t,a,i)}const n=function(e,t,a,i,l){$("#java"+t+"_filecount").val(e).trigger("updated"),window["uploadQuestionController_"+t].displayUploadedFiles(e,t,a,i,l)};var s=function(e,a){var i,l=$("#"+e+"_filename_"+a).val(),n=$("#"+e+"_name_"+a).val(),s=parseInt($("#java"+e+"_filecount").val()),o=parseInt($("#"+e+"_licount").val());$.ajax({method:"POST",url:uploadurl,data:{delete:1,fieldname:e,filename:l,name:n,YII_CSRF_TOKEN:t.csrfToken}}).done((function(t){for($("#notice").html('<p class="alert alert-success"><span class="fa fa-check ri-check-fill"></span>&nbsp;'+t+"</p>"),setTimeout((function(){$(".success").remove()}),5e3),$("#"+e+"_li_"+a).hide(),s--,$("#java"+e+"_filecount").val(s),i=$("#"+e+"_file_index_"+a).val(),j=a;j<=o;j++)$("#"+e+"_li_"+j).is(":visible")&&($("#"+e+"_file_index_"+j).val(i),i++);var l=parseInt($("#"+e+"_minfiles").val()),n=parseInt($("#"+e+"_maxfiles").val());s<l?$("#uploadstatus").html(uploadLang.errorNeedMore.replace("%s",l-s)):$("#uploadstatus").html(uploadLang.errorMoreAllowed.replace("%s",n-s))}))};return{init:function(){i()},saveAndExit:function(e,t,a,i){var n=parseInt($("#java"+e+"_filecount").val()),s=parseInt($("#"+e+"_minfiles").val());return 0!=s&&n<s&&showpopups?!!confirm(uploadLang.errorNeedMoreConfirm.replace("%s",s-n))&&(l(e,t,a,i),!0):(l(e,t,a,i),!0)}}};function escapeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}window.getUploadHandler=function(e,t){return window.currentUploadHandler=new uploadHandler(e,t),window.currentUploadHandler.init(),window.currentUploadHandler}}));
     //# sourceMappingURL=uploadquestion.min.js.map
    
  • assets/packages/questions/upload/build/uploadquestion.min.js.map+1 1 modified
  • assets/packages/questions/upload/src/modaldialog.js+2 2 modified
    @@ -120,8 +120,8 @@ class UploadQuestionController {
                         imageOrPlaceholderHtml = '<div class="upload-placeholder"></div>';
                     }
     
    -                title = (show_title != 0) ? item.title : '';
    -                comment = (show_comment != 0) ? item.comment : '';
    +                title = (show_title != 0) ? htmlentities(item.title) : '';
    +                comment = (show_comment != 0) ? htmlentities(item.comment) : '';
                     name = item.name;
                     filepointer = iterator;
                     const rowHtml = this.replaceWithObject(templateHtml, {imageOrPlaceholder, imageOrPlaceholderHtml, title, comment, name, filepointer});
    

Vulnerability mechanics

Root cause

"Missing HTML entity encoding on user-controlled title and comment fields in the file upload question template allows stored cross-site scripting."

Attack vector

An attacker who can submit a file upload response (e.g., a survey participant) can inject arbitrary HTML/JavaScript into the `title` or `comment` fields of an uploaded file. When the uploaded files are displayed to other users (including administrators reviewing responses), the unsanitized values are inserted directly into the DOM via `replaceWithObject` template substitution [patch_id=438591]. The payload executes in the context of the victim's session, enabling data theft, session hijacking, or further compromise. No special network position is required beyond normal survey access.

Affected code

The vulnerability exists in the file upload question rendering code. In `assets/packages/questions/upload/src/modaldialog.js` (lines 123-124) and the compiled `assets/packages/questions/upload/build/uploadquestion.js` (lines 786-787), the `title` and `comment` variables are assigned directly from `item.title` and `item.comment` without sanitization. These values are later used in `replaceWithObject()` to populate HTML templates. The minified bundle `uploadquestion.min.js` contains the equivalent unsanitized logic.

What the fix does

The patch wraps `item.title` and `item.comment` with the existing `htmlentities()` function in both `modaldialog.js` and the compiled `uploadquestion.js` [patch_id=438591]. This encodes HTML special characters (`<`, `>`, `&`, `"`, `'`) before the values are interpolated into the template, preventing injected markup from being interpreted as DOM elements. The same change is applied in the minified bundle (`uploadquestion.min.js`). A secondary whitespace-only change adds a space before the closing `>` of the loading icon `<i>` element, which is unrelated to the security fix.

Preconditions

  • configThe survey must include a file upload question type with title and/or comment fields enabled.
  • authThe attacker must be able to submit a file upload response (authenticated or anonymous, depending on survey settings).
  • inputA victim (e.g., survey administrator or other respondent) must view the page that displays the uploaded file metadata.

Generated on May 19, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.