CVE-2016-10537
Description
Backbone.js 0.3.3 and earlier contain a cross-site scripting (XSS) vulnerability in Model#escape due to incomplete HTML entity encoding.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Backbone.js 0.3.3 and earlier contain a cross-site scripting (XSS) vulnerability in Model#escape due to incomplete HTML entity encoding.
Vulnerability
Backbone.js versions 0.3.3 and earlier [1][2] contain a cross-site scripting (XSS) vulnerability in the Model#escape function. The function uses a regular expression to replace HTML special characters, but the regex fails to convert certain characters, such as < to < [3]. This allows un-sanitized user-supplied input to be rendered as HTML in the application [3].
Exploitation
An attacker must first be able to supply arbitrary input to a Backbone model attribute [3]. This typically requires the attacker to have some mechanism to inject data, such as through a form field, URL parameter, or API endpoint that populates a model. The vulnerable code path is triggered when the application renders the model's attribute using the Model#escape function, which is intended to escape HTML but fails to properly encode the input. No user interaction beyond normal page rendering is required if the attacker can control model data that is then displayed via escape().
Impact
Successful exploitation allows an attacker to inject arbitrary HTML and JavaScript into the application's context [3]. This can lead to data theft, session hijacking, defacement, or other client-side attacks, depending on the application's trust level and the attacker's objectives. The impact is limited to the browser's security context of the application; the attacker does not gain server-side access.
Mitigation
The vulnerability was addressed in Backbone.js version 0.5.0, which was released after 0.3.3 [4]. The fix corrected the regular expression to properly encode all HTML special characters. Users should upgrade to Backbone.js 0.5.0 or later [1]. For applications still using an affected version, the recommended mitigation is to update the library immediately. There is no known workaround other than upgrading, as the Model#escape functionality is integral to data rendering in Backbone applications.
AI Insight generated on May 22, 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.
| Package | Affected versions | Patched versions |
|---|---|---|
backbonenpm | >= 0.3.3, < 0.5.0 | 0.5.0 |
Affected products
2- HackerOne/backbone node modulev5Range: <= 0.3.3
Patches
20cdc525961d3Fixed escapeHTML function
1 file changed · +1 −1
backbone.js+1 −1 modified@@ -1079,7 +1079,7 @@ // Helper function to escape a string for HTML rendering. var escapeHTML = function(string) { - return string.replace(/&(?!\w+;)/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); + return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); }; }).call(this);
7ae0384120c2first draft of Model#escape
2 files changed · +32 −2
backbone.js+21 −1 modified@@ -116,6 +116,7 @@ attributes || (attributes = {}); if (this.defaults) attributes = _.extend({}, this.defaults, attributes); this.attributes = {}; + this._escapedAttributes = {}; this.cid = _.uniqueId('c'); this.set(attributes, {silent : true}); this._previousAttributes = _.clone(this.attributes); @@ -147,6 +148,14 @@ return this.attributes[attr]; }, + // Get the HTML-escaped value of an attribute. + escape : function(attr) { + var html; + if (html = this._escapedAttributes[attr]) return html; + var val = this.attributes[attr]; + return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : val); + }, + // Set a hash of model attributes on the object, firing `"change"` unless you // choose to silence it. set : function(attrs, options) { @@ -155,7 +164,7 @@ options || (options = {}); if (!attrs) return this; if (attrs.attributes) attrs = attrs.attributes; - var now = this.attributes; + var now = this.attributes, escaped = this._escapedAttributes; // Run validation. if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false; @@ -168,6 +177,7 @@ var val = attrs[attr]; if (!_.isEqual(now[attr], val)) { now[attr] = val; + delete escaped[attr]; if (!options.silent) { this._changed = true; this.trigger('change:' + attr, this, val); @@ -193,6 +203,7 @@ // Remove the attribute. delete this.attributes[attr]; + delete this._escapedAttributes[attr]; if (!options.silent) { this._changed = true; this.trigger('change:' + attr, this); @@ -213,6 +224,7 @@ if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false; this.attributes = {}; + this._escapedAttributes = {}; if (!options.silent) { this._changed = true; for (attr in old) { @@ -981,4 +993,12 @@ return _.isFunction(object.url) ? object.url() : object.url; }; + // Helper function to escape a string for HTML rendering. + var escapeHTML = function(string) { + return string.replace(/&(?!\w+;)/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"'); + }; + })();
test/model.js+11 −1 modified@@ -94,6 +94,16 @@ $(document).ready(function() { equals(doc.get('author'), 'Bill Shakespeare'); }); + test("Model: escape", function() { + equals(doc.escape('title'), 'The Tempest'); + doc.set({audience: 'Bill & Bob'}); + equals(doc.escape('audience'), 'Bill & Bob'); + doc.set({audience: 'Tim > Joan'}); + equals(doc.escape('audience'), 'Tim > Joan'); + doc.unset('audience'); + equals(doc.escape('audience'), ''); + }); + test("Model: set and unset", function() { attrs = { 'foo': 1, 'bar': 2, 'baz': 3}; a = new Backbone.Model(attrs); @@ -151,7 +161,7 @@ $(document).ready(function() { model.change(); equals(model.get('name'), 'Rob'); }); - + test("Model: save within change event", function () { var model = new Backbone.Model({firstName : "Taylor", lastName: "Swift"}); model.bind('change', function () {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-j6p2-cx3w-6jcpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-10537ghsaADVISORY
- backbonejs.orgghsaWEB
- github.com/jashkenas/backbone/commit/0cdc525961d3fa98e810ffae6bcc8e3838e36d93ghsaWEB
- github.com/jashkenas/backbone/commit/7ae0384120c2552e1c426cda7fb02fdce6ef1076ghsaWEB
- github.com/jashkenas/backbone/compare/0.3.3...0.5.0ghsax_refsource_MISCWEB
- nodesecurity.io/advisories/108mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.