prototype: Automatically strip security delimiter comments from JSON strings before evaling them. The default delimiter is '/*-secure- ... */' or you can specify your own with the Prototype.JSONFilter regular expression. If you wrap your JSON response bodies in this delimiter on the server side, rogue external sites can't hijack potentially sensitive data via <script> tags. Closes #7910.
This commit is contained in:
parent
643b7bec37
commit
fea6bc1a21
@ -1,5 +1,8 @@
|
||||
*SVN*
|
||||
|
||||
* Automatically strip security delimiter comments from JSON strings before evaling them. The default delimiter is '/*-secure- ... */' or you can specify your own with the Prototype.JSONFilter regular expression. If you wrap your JSON response bodies in this delimiter on the server side, rogue external sites can't hijack potentially sensitive data via <script> tags. Closes #7910. [Tobie Langel]
|
||||
For more details on potential security problems, see: http://www.fortifysoftware.com/servlet/downloads/public/JavaScript_Hijacking.pdf
|
||||
|
||||
* Add extra spacing so Array#toJSON and Hash#toJSON generate YAML-loadable JSON. Closes #7883. [Andrew Dupont]
|
||||
|
||||
* Fix Form.request for forms containing an input element with name="action". Closes #8063. [Thomas Fuchs, Mislav Marohnić]
|
||||
|
@ -212,13 +212,13 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
|
||||
evalJSON: function() {
|
||||
try {
|
||||
var json = this.getHeader('X-JSON');
|
||||
return json ? eval('(' + json + ')') : null;
|
||||
return json ? json.evalJSON() : null;
|
||||
} catch (e) { return null }
|
||||
},
|
||||
|
||||
evalResponse: function() {
|
||||
try {
|
||||
return eval(this.transport.responseText);
|
||||
return eval((this.transport.responseText || '').unfilterJSON());
|
||||
} catch (e) {
|
||||
this.dispatchException(e);
|
||||
}
|
||||
|
7
src/prototype.js
vendored
7
src/prototype.js
vendored
@ -9,6 +9,7 @@ var Prototype = {
|
||||
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
|
||||
Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
|
||||
},
|
||||
|
||||
BrowserFeatures: {
|
||||
XPath: !!document.evaluate,
|
||||
ElementExtensions: !!window.HTMLElement,
|
||||
@ -16,9 +17,11 @@ var Prototype = {
|
||||
(document.createElement('div').__proto__ !==
|
||||
document.createElement('form').__proto__)
|
||||
},
|
||||
|
||||
|
||||
ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
|
||||
emptyFunction: function() {},
|
||||
JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,
|
||||
|
||||
emptyFunction: function() { },
|
||||
K: function(x) { return x }
|
||||
}
|
||||
|
||||
|
@ -163,12 +163,17 @@ Object.extend(String.prototype, {
|
||||
return this.inspect(true);
|
||||
},
|
||||
|
||||
unfilterJSON: function(filter) {
|
||||
return this.sub(filter || Prototype.JSONFilter, '#{1}');
|
||||
},
|
||||
|
||||
evalJSON: function(sanitize) {
|
||||
var json = this.unfilterJSON();
|
||||
try {
|
||||
if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(this)))
|
||||
return eval('(' + this + ')');
|
||||
} catch (e) {}
|
||||
throw new SyntaxError('Badly formated JSON string: ' + this.inspect());
|
||||
if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
|
||||
return eval('(' + json + ')');
|
||||
} catch (e) { }
|
||||
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
|
||||
},
|
||||
|
||||
include: function(pattern) {
|
||||
|
@ -430,7 +430,13 @@
|
||||
attackTarget = "Not scared!";
|
||||
assertRaise('SyntaxError', function(){dangerous.evalJSON(true)});
|
||||
assertEqual("Not scared!", attackTarget);
|
||||
}}
|
||||
|
||||
assertEqual('hello world!', ('/*-secure-\n' + valid + '\n*/').evalJSON().test);
|
||||
var temp = Prototype.JSONFilter;
|
||||
Prototype.JSONFilter = /^\/\*(.*)\*\/$/; // test custom delimiters.
|
||||
assertEqual('hello world!', ('/*' + valid + '*/').evalJSON().test);
|
||||
Prototype.JSONFilter = temp;
|
||||
}}
|
||||
}, 'testlog');
|
||||
// ]]>
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user