VYPR
Moderate severityOSV Advisory· Published Feb 13, 2020· Updated Aug 4, 2024

CVE-2019-10785

CVE-2019-10785

Description

dojox is vulnerable to Cross-site Scripting in all versions before version 1.16.1, 1.15.2, 1.14.5, 1.13.6, 1.12.7 and 1.11.9. This is due to dojox.xmpp.util.xmlEncode only encoding the first occurrence of each character, not all of them.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
dojoxnpm
< 1.11.91.11.9
dojoxnpm
>= 1.12.0, < 1.12.71.12.7
dojoxnpm
>= 1.13.0, < 1.13.61.13.6
dojoxnpm
>= 1.14.0, < 1.14.51.14.5
dojoxnpm
>= 1.15.0, < 1.15.21.15.2
dojoxnpm
>= 1.16.0, < 1.16.11.16.1

Affected products

1
  • Range: 1.11.0, 1.11.1, 1.11.2, …

Patches

1
abd033a787c7

Merge pull request #315 from devpaul/xmlEncode-xxs

https://github.com/dojo/dojoxMatthew GaddFeb 3, 2020via ghsa
3 files changed · +84 87
  • dtl/dom.js+1 1 modified
    @@ -94,7 +94,7 @@ define([
     										var replacement = "";
     										for(var p = 2, pl = pair.length; p < pl; p++){
     											if(p == 2){
    -												replacement += "<" + tag + ' dtlinstruction="{% ' + token[k].replace('"', '\\"') + ' %}">';
    +												replacement += "<" + tag + ' dtlinstruction="{% ' + token[k].replace(/"/g, '\\"') + ' %}">';
     											}else if(tag == pair[p]) {
     												continue;
     											}else{
    
  • widget/RollingList.js+79 79 modified
    @@ -30,11 +30,11 @@ dojo.declare("dojox.widget._RollingListPane",
     	// parentWidget: dojox.widget.RollingList
     	//		Our rolling list widget
     	parentWidget: null,
    -	
    +
     	// parentPane: dojox.widget._RollingListPane
     	//		The pane that immediately precedes ours
     	parentPane: null,
    -			
    +
     	// store: store
     	//		the store we must use
     	store: null,
    @@ -46,23 +46,23 @@ dojo.declare("dojox.widget._RollingListPane",
     	//		see if the pane needs to be reloaded (store notifications are handled)
     	//		by the pane
     	items: null,
    -	
    +
     	// query: object
     	//		a query to pass to the datastore.  This is only used if items are null
     	query: null,
    -	
    +
     	// queryOptions: object
     	//		query options to be passed to the datastore
     	queryOptions: null,
    -	
    +
     	// focusByNode: boolean
     	//		set to false if the subclass will handle its own node focusing
     	_focusByNode: true,
    -	
    +
     	// minWidth: integer
     	//		the width (in px) for this pane
     	minWidth: 0,
    -	
    +
     	_setContentAndScroll: function(/*String|DomNode|Nodelist*/cont, /*Boolean?*/isFakeContent){
     		// summary:
     		//		sets the value of the content and scrolls it into view
    @@ -79,19 +79,19 @@ dojo.declare("dojox.widget._RollingListPane",
     			dojo.marginBox(n, {w: min});
     		}
     	},
    -	
    +
     	_onMinWidthChange: function(v){
     		// Called when the min width of a pane has changed
     		this._updateNodeWidth(this.domNode, v);
     	},
    -	
    +
     	_setMinWidthAttr: function(v){
     		if(v !== this.minWidth){
     			this.minWidth = v;
     			this._onMinWidthChange(v);
     		}
     	},
    -	
    +
     	startup: function(){
     		if(this._started){ return; }
     		if(this.store && this.store.getFeatures()["dojo.data.api.Notification"]){
    @@ -123,7 +123,7 @@ dojo.declare("dojox.widget._RollingListPane",
     			this.parentWidget._onExecute();
     		}
     	},
    -	
    +
     	focus: function(/*boolean*/force){
     		// summary:
     		//		sets the focus to this current widget
    @@ -156,7 +156,7 @@ dojo.declare("dojox.widget._RollingListPane",
     			this._doQuery();
     		}
     	},
    -	
    +
     	_doLoadItems: function(/*item[]*/items, /*function*/callback){
     		// summary:
     		//		loads the given items, and then calls the callback when they
    @@ -181,7 +181,7 @@ dojo.declare("dojox.widget._RollingListPane",
     			});
     		}
     	},
    -	
    +
     	_doQuery: function(){
     		// summary:
     		//		either runs the query or loads potentially not-yet-loaded items.
    @@ -218,7 +218,7 @@ dojo.declare("dojox.widget._RollingListPane",
     		}
     		return false;
     	},
    -	
    +
     	_onSetItem: function(/* item */ item,
     					/* attribute-name-string */ attribute,
     					/* Object|Array */ oldValue,
    @@ -229,7 +229,7 @@ dojo.declare("dojox.widget._RollingListPane",
     			this.refresh();
     		}
     	},
    -	
    +
     	_onNewItem: function(/* item */ newItem, /*object?*/ parentInfo){
     		// summary:
     		//		called when an item is added to the store
    @@ -243,7 +243,7 @@ dojo.declare("dojox.widget._RollingListPane",
     			this.refresh();
     		}
     	},
    -	
    +
     	_onDeleteItem: function(/* item */ deletedItem){
     		// summary:
     		//		called when an item is removed from the store
    @@ -254,13 +254,13 @@ dojo.declare("dojox.widget._RollingListPane",
     			this.refresh();
     		}
     	},
    -	
    +
     	onFetchStart: function(){
     		// summary:
     		//		called before a fetch starts
     		return this.loadingMessage;
     	},
    -	
    +
     	onFetchError: function(/*Error*/ error){
     		// summary:
     		//		called when a fetch error occurs.
    @@ -272,13 +272,13 @@ dojo.declare("dojox.widget._RollingListPane",
     		//		called before a load starts
     		return this.loadingMessage;
     	},
    -	
    +
     	onLoadError: function(/*Error*/ error){
     		// summary:
     		//		called when a load error occurs.
     		return this.errorMessage;
     	},
    -	
    +
     	onItems: function(){
     		// summary:
     		//		called after a fetch or load - at this point, this.items should be
    @@ -289,14 +289,14 @@ dojo.declare("dojox.widget._RollingListPane",
     		}
     		this._onLoadHandler();
     	}
    -			
    +
     });
     
     dojo.declare("dojox.widget._RollingListGroupPane",
     	[dojox.widget._RollingListPane], {
     	// summary:
     	//		a pane that will handle groups (treats them as menu items)
    -	
    +
     	// templateString: string
     	//		our template
     	templateString: '<div><div dojoAttachPoint="containerNode"></div>' +
    @@ -307,7 +307,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     	// _menu: dijit.Menu
     	//		The menu that we will call addChild() on for adding items
     	_menu: null,
    -	
    +
     	_setContent: function(/*String|DomNode|Nodelist*/cont){
     		if(!this._menu){
     			// Only set the content if we don't already have a menu
    @@ -371,7 +371,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     		this.inherited(arguments);
     		this._onMinWidthChange(this.minWidth);
     	},
    -	
    +
     	_checkScrollConnection: function(doLoad){
     		// summary:
     		//		checks whether or not we need to connect to our onscroll
    @@ -388,12 +388,12 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     			this._scrollConn = this.connect(this.domNode, "onscroll", "_onScrollPane");
     		}
     	},
    -	
    +
     	startup: function(){
     		this.inherited(arguments);
     		this.parentWidget._updateClass(this.domNode, "GroupPane");
     	},
    -	
    +
     	focus: function(/*boolean*/force){
     		// summary:
     		//		sets the focus to this current widget
    @@ -402,7 +402,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     				this.disconnect(this._pendingFocus);
     			}
     			delete this._pendingFocus;
    -			
    +
     			// We focus the right widget - either the focusedChild, the
     			// selected node, the first menu item, or the menu itself
     			var focusWidget = this._menu.focusedChild;
    @@ -437,7 +437,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     			this._pendingFocus = this.connect(this, "onItems", "focus");
     		}
     	},
    -	
    +
     	_getMenu: function(){
     		// summary:
     		//		returns a widget to be used for the container widget.
    @@ -479,7 +479,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     		}
     		return menu;
     	},
    -	
    +
     	_onScrollPane: function(){
     		// summary:
     		//		called when the pane has been scrolled - it sets a timeout
    @@ -490,7 +490,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     		}
     		this._visibleLoadPending = window.setTimeout(dojo.hitch(this, "_loadVisibleItems"), 500);
     	},
    -	
    +
     	_loadVisibleItems: function(){
     		// summary:
     		//		loads the items that are currently visible in the pane
    @@ -545,7 +545,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     		});
     		this._doLoadItems(itemsToLoad, onItems);
     	},
    -	
    +
     	_getSelected: function(/*dijit.Menu?*/ menu){
     		// summary:
     		//		returns the selected menu item - or null if none are selected
    @@ -560,7 +560,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
     		}
     		return null;
     	},
    -	
    +
     	_setSelected: function(/*dijit.MenuItem?*/ item, /*dijit.Menu?*/ menu){
     		// summary:
     		//		selects the given item in the given menu (defaults to pane's menu)
    @@ -577,46 +577,46 @@ dojo.declare("dojox.widget.RollingList",
     	[dijit._Widget, dijit._Templated, dijit._Container], {
     	// summary:
     	//		a rolling list that can be tied to a data store with children
    -		
    +
     	// templateString: String
     	//		The template to be used to construct the widget.
     	templateString: dojo.cache("dojox.widget", "RollingList/RollingList.html"),
     	widgetsInTemplate: true,
    -	
    +
     	// className: string
     	//		an additional class (or space-separated classes) to add for our widget
     	className: "",
    -	
    +
     	// store: store
     	//		the store we must use
     	store: null,
    -	
    +
     	// query: object
     	//		a query to pass to the datastore.  This is only used if items are null
     	query: null,
    -	
    +
     	// queryOptions: object
     	//		query options to be passed to the datastore
     	queryOptions: null,
    -	
    +
     	// childrenAttrs: String[]
     	//		one ore more attributes that holds children of a node
     	childrenAttrs: ["children"],
     
     	// parentAttr: string
     	//		the attribute to read for finding our parent item (if any)
     	parentAttr: "",
    -	
    +
     	// value: item
     	//		The value that has been selected
     	value: null,
    -	
    +
     	// executeOnDblClick: boolean
     	//		Set to true if you want to call onExecute when an item is
     	//		double-clicked, false if you want to call onExecute yourself. (mainly
     	//		used for popups to control how they want to be handled)
     	executeOnDblClick: true,
    -	
    +
     	// preloadItems: boolean or int
     	//		if set to true, then onItems will be called only *after* all items have
     	//		been loaded (ie store.isLoaded will return true for all of them).  If
    @@ -625,16 +625,16 @@ dojo.declare("dojox.widget.RollingList",
     	//		of the integer.  The onItems function will need to be aware of handling
     	//		items that may not be loaded
     	preloadItems: false,
    -	
    +
     	// showButtons: boolean
     	//		if set to true, then buttons for "OK" and "Cancel" will be provided
     	showButtons: false,
    -	
    +
     	// okButtonLabel: string
     	//		The string to use for the OK button - will use dijit's common "OK" string
     	//		if not set
     	okButtonLabel: "",
    -	
    +
     	// cancelButtonLabel: string
     	//		The string to use for the Cancel button - will use dijit's common
     	//		"Cancel" string if not set
    @@ -644,7 +644,7 @@ dojo.declare("dojox.widget.RollingList",
     	//		the minimum pane width (in px) for all child panes.  If they are narrower,
     	//		the width will be increased to this value.
     	minPaneWidth: 0,
    -	
    +
     	postMixInProperties: function(){
     		// summary:
     		//		Mix in our labels, if they are not set
    @@ -653,7 +653,7 @@ dojo.declare("dojox.widget.RollingList",
     		this.okButtonLabel = this.okButtonLabel || loc.buttonOk;
     		this.cancelButtonLabel = this.cancelButtonLabel || loc.buttonCancel;
     	},
    -	
    +
     	_setShowButtonsAttr: function(doShow){
     		// summary:
     		//		Sets the visibility of the buttons for the widget
    @@ -672,7 +672,7 @@ dojo.declare("dojox.widget.RollingList",
     			}
     		}
     	},
    -	
    +
     	_itemsMatch: function(/*item*/ item1, /*item*/ item2){
     		// summary:
     		//		returns whether or not the two items match - checks ID if
    @@ -685,7 +685,7 @@ dojo.declare("dojox.widget.RollingList",
     		return (item1 == item2 ||
     			(this._isIdentity && this.store.getIdentity(item1) == this.store.getIdentity(item2)));
     	},
    -	
    +
     	_removeAfter: function(/*Widget or int*/ idx){
     		// summary:
     		//		removes all widgets after the given widget (or index)
    @@ -713,7 +713,7 @@ dojo.declare("dojox.widget.RollingList",
     			this._setValue(selItem);
     		}
     	},
    -	
    +
     	addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
     		// summary:
     		//		adds a child to this rolling list - if passed an insertIndex,
    @@ -732,7 +732,7 @@ dojo.declare("dojox.widget.RollingList",
     			widget.focus();
     		}
     	},
    -	
    +
     	_setMinPaneWidthAttr: function(value){
     		// summary:
     		//		Sets the min pane width of all children
    @@ -743,7 +743,7 @@ dojo.declare("dojox.widget.RollingList",
     			});
     		}
     	},
    -	
    +
     	_updateClass: function(/* Node */ node, /* String */ type, /* Object? */ options){
     		// summary:
     		//		sets the state of the given node with the given type and options
    @@ -766,7 +766,7 @@ dojo.declare("dojox.widget.RollingList",
     			}
     		});
     	},
    -	
    +
     	scrollIntoView: function(/*dijit._Widget*/ childWidget){
     		// summary:
     		//		scrolls the given widget into view
    @@ -782,11 +782,11 @@ dojo.declare("dojox.widget.RollingList",
     			return;
     		}), 1);
     	},
    -	
    +
     	resize: function(args){
     		dijit.layout._LayoutWidget.prototype.resize.call(this, args);
     	},
    -	
    +
     	layout: function(){
     		var children = this.getChildren();
     		if(this._contentBox){
    @@ -809,7 +809,7 @@ dojo.declare("dojox.widget.RollingList",
     			}
     		}
     	},
    -	
    +
     	_onChange: function(/*item*/ value){
     		this.onChange(value);
     	},
    @@ -823,7 +823,7 @@ dojo.declare("dojox.widget.RollingList",
     			this._onChange(value);
     		}
     	},
    -	
    +
     	_setValueAttr: function(/* item */ value){
     		// summary:
     		//		sets the value of this widget to the given store item
    @@ -836,7 +836,7 @@ dojo.declare("dojox.widget.RollingList",
     			this._onItemClick(null, pane, null, null);
     			return;
     		}
    -		
    +
     		var fetchParentItems = dojo.hitch(this, function(/*item*/ item, /*function*/callback){
     			// summary:
     			//		Fetches the parent items for the given item
    @@ -880,7 +880,7 @@ dojo.declare("dojox.widget.RollingList",
     				}, this);
     			}
     		});
    -		
    +
     		var setFromChain = dojo.hitch(this, function(/*item[]*/itemChain, /*integer*/idx){
     			// summary:
     			//		Sets the value of the widget at the given index in the chain - onchanges are not
    @@ -922,7 +922,7 @@ dojo.declare("dojox.widget.RollingList",
     				this.set("value", null);
     			}
     		});
    -		
    +
     		var parentChain = [];
     		var onParents = dojo.hitch(this, function(/*item[]*/ parents){
     			// summary:
    @@ -938,7 +938,7 @@ dojo.declare("dojox.widget.RollingList",
     				setFromChain(parentChain, 0);
     			}
     		});
    -		
    +
     		// Only set the value in display if we are shown - if we are in a dropdown,
     		// and are hidden, don't actually do the scrolling in the display (it can
     		// mess up layouts)
    @@ -949,11 +949,11 @@ dojo.declare("dojox.widget.RollingList",
     			onParents([value]);
     		}
     	},
    -	
    +
     	_onItemClick: function(/* Event */ evt, /* dijit._Contained */ pane, /* item */ item, /* item[]? */ children){
     		// summary:
     		//		internally called when a widget should pop up its child
    -		
    +
     		if(evt){
     			var itemPane = this._getPaneForItem(item, pane, children);
     			var alreadySelected = (evt.type == "click" && evt.alreadySelected);
    @@ -984,7 +984,7 @@ dojo.declare("dojox.widget.RollingList",
     		}
     		this._visibleItem = item;
     	},
    -	
    +
     	_getPaneForItem: function(/* item? */ item, /* dijit._Contained? */ parentPane, /* item[]? */ children){
     		// summary:
     		//		gets the pane for the given item, and mixes in our needed parts
    @@ -1004,7 +1004,7 @@ dojo.declare("dojox.widget.RollingList",
     		}
     		return ret;
     	},
    -	
    +
     	_getMenuItemForItem: function(/*item*/ item, /* dijit._Contained */ parentPane){
     		// summary:
     		//		returns a widget for the given store item.  The returned
    @@ -1050,7 +1050,7 @@ dojo.declare("dojox.widget.RollingList",
     			widgetItem.store = this.store;
     			widgetItem.item = item;
     			if(!widgetItem.label){
    -				widgetItem.attr("label", this.store.getLabel(item).replace(/</,"&lt;"));
    +				widgetItem.attr("label", this.store.getLabel(item).replace(/</g,"&lt;"));
     			}
     			if(widgetItem.focusNode){
     				var self = this;
    @@ -1084,7 +1084,7 @@ dojo.declare("dojox.widget.RollingList",
     			return widgetItem;
     		}
     	},
    -	
    +
     	_setStore: function(/* dojo/data/api/Read */ store){
     		// summary:
     		//		sets the store for this widget */
    @@ -1094,7 +1094,7 @@ dojo.declare("dojox.widget.RollingList",
     		var rootPane = this._getPaneForItem();
     		this.addChild(rootPane, 0);
     	},
    -	
    +
     	_onKey: function(/*Event*/ e){
     		// summary:
     		//		called when a keypress event happens on this widget
    @@ -1111,29 +1111,29 @@ dojo.declare("dojox.widget.RollingList",
     			return;
     		}
     	},
    -	
    +
     	_resetValue: function(){
     		// summary:
     		//		function called when the value is reset.
     		this.set("value", this._lastExecutedValue);
     	},
    -	
    +
     	_onCancel: function(){
     		// summary:
     		//		function called when the cancel button is clicked.  It
     		//		resets its value to whatever was last executed and then cancels
     		this._resetValue();
     		this.onCancel();
     	},
    -	
    +
     	_onExecute: function(){
     		// summary:
     		//		function called when the OK button is clicked or when an
     		//		item is selected (double-clicked or "enter" pressed on it)
     		this._lastExecutedValue = this.get("value");
     		this.onExecute();
     	},
    -	
    +
     	focus: function(){
     		// summary:
     		//		sets the focus state of this widget
    @@ -1156,7 +1156,7 @@ dojo.declare("dojox.widget.RollingList",
     			}
     		}
     	},
    -	
    +
     	handleKey:function(/*Event*/e){
     		// summary:
     		//		handle the key for the given event - called by dropdown
    @@ -1171,7 +1171,7 @@ dojo.declare("dojox.widget.RollingList",
     		}
     		return true;
     	},
    -	
    +
     	_updateChildClasses: function(){
     		// summary:
     		//		Called when a child is added or removed - so that we can
    @@ -1198,7 +1198,7 @@ dojo.declare("dojox.widget.RollingList",
     		this.inherited(arguments);
     		this._lastExecutedValue = this.get("value");
     	},
    -	
    +
     	getChildItems: function(/*item*/ item){
     		// summary:
     		//		Returns the child items for the given store item
    @@ -1211,7 +1211,7 @@ dojo.declare("dojox.widget.RollingList",
     		});
     		return childItems;
     	},
    -	
    +
     	getMenuItemForItem: function(/*item*/ item, /* dijit._Contained */ parentPane, /* item[]? */ children){
     		// summary:
     		//		user overridable function to return a widget for the given item
    @@ -1237,20 +1237,20 @@ dojo.declare("dojox.widget.RollingList",
     		// summary:
     		//		called when an item is clicked - it receives the store item
     	},
    -	
    +
     	onExecute: function(){
     		// summary:
     		//		exists so that popups don't disappear too soon
     	},
    -	
    +
     	onCancel: function(){
     		// summary:
     		//		exists so that we can close ourselves if we wish
     	},
    -	
    +
     	onChange: function(/* item */ value){
     		// summary:
     		//		called when the value of this widget has changed
     	}
    -	
    +
     });
    
  • xmpp/util.js+4 7 modified
    @@ -3,10 +3,7 @@ dojo.require("dojox.string.Builder");
     dojo.require("dojox.encoding.base64");
     
     dojox.xmpp.util.xmlEncode = function(str) {
    -	if(str) {
    -		str = str.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;").replace("'", "&apos;").replace('"', "&quot;");
    -	}
    -	return str;
    +	return dojo.string.escape(str);
     };
     
     dojox.xmpp.util.encodeJid = function(jid) {
    @@ -49,7 +46,7 @@ dojox.xmpp.util.encodeJid = function(jid) {
     };
     
     dojox.xmpp.util.decodeJid = function(jid) {
    -	
    +
     	jid = jid.replace(/\\([23][02367acef])/g, function(match) {
     			switch(match){
     				case "\\20" :
    @@ -73,7 +70,7 @@ dojox.xmpp.util.decodeJid = function(jid) {
     			}
     			return "ARG";
     	});
    -	
    +
     	return jid;
     };
     
    @@ -87,7 +84,7 @@ dojox.xmpp.util.createElement = function(tag, attributes, terminal){
     		elem.append(attributes[attr]);
     		elem.append('" ');
     	}
    -	
    +
     	if (terminal){
     		elem.append("/>");
     	}else{
    

Vulnerability mechanics

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

References

9

News mentions

0

No linked articles in our index yet.