summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/secure/sandbox.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/secure/sandbox.js')
-rw-r--r--js/dojo-1.7.2/dojox/secure/sandbox.js348
1 files changed, 348 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/secure/sandbox.js b/js/dojo-1.7.2/dojox/secure/sandbox.js
new file mode 100644
index 0000000..70cc782
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/sandbox.js
@@ -0,0 +1,348 @@
+//>>built
+// wrapped by build app
+define("dojox/secure/sandbox", ["dijit","dojo","dojox","dojo/require!dojox/secure/DOM,dojox/secure/capability,dojo/NodeList-fx,dojo/_base/url"], function(dijit,dojo,dojox){
+dojo.provide("dojox.secure.sandbox");
+dojo.require("dojox.secure.DOM");
+dojo.require("dojox.secure.capability");
+dojo.require("dojo.NodeList-fx");
+dojo.require("dojo._base.url");
+
+(function() {
+ var oldTimeout = setTimeout;
+ var oldInterval = setInterval;
+ if({}.__proto__){
+ // mozilla has unsafe methods on array
+ var fixMozArrayFunction = function (name) {
+ var method = Array.prototype[name];
+ if(method && !method.fixed){
+ (Array.prototype[name] = function () {
+ if (this == window) {
+ throw new TypeError("Called with wrong this");
+ }
+ return method.apply(this, arguments);
+ }).fixed = true;
+ }
+ };
+ // these are not safe in mozilla
+ fixMozArrayFunction('concat');
+ fixMozArrayFunction('reverse');
+ fixMozArrayFunction('sort');
+ fixMozArrayFunction("slice");
+ fixMozArrayFunction("forEach");
+ fixMozArrayFunction("filter");
+ fixMozArrayFunction("reduce");
+ fixMozArrayFunction("reduceRight");
+ fixMozArrayFunction("every");
+ fixMozArrayFunction("map");
+ fixMozArrayFunction("some");
+ }
+ var xhrGet = function(){
+ return dojo.xhrGet.apply(dojo,arguments);
+ };
+ dojox.secure.sandbox = function(element) {
+ // summary:
+ // Creates a secure sandbox from which scripts and HTML can be loaded that
+ // will only be able to access the provided element and it's descendants, the
+ // rest of the DOM and JS environment will not be accessible to the sandboxed
+ // scripts and HTML.
+ //
+ // element:
+ // The DOM element to use as the container for the sandbox
+ //
+ // description:
+ // This function will create and return a sandbox object (see dojox.secure.__Sandbox)
+ // for the provided element.
+ var wrap = dojox.secure.DOM(element);
+ element = wrap(element);
+ var document = element.ownerDocument;
+ var mixin, dojo = dojox.secure._safeDojoFunctions(element,wrap);
+ var imports= [];
+ var safeCalls = ["isNaN","isFinite","parseInt","parseFloat","escape","unescape",
+ "encodeURI","encodeURIComponent","decodeURI","decodeURIComponent",
+ "alert","confirm","prompt", // some people may not want to allow these to be called, but they don't break capability-limiting
+ "Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError",
+ "Date","RegExp","Number","Object","Array","String","Math",
+ //"ADSAFE", // not using ADSAFE runtime for the time being
+ "setTimeout","setInterval","clearTimeout","clearInterval", // we make these safe below
+ "dojo","get","set","forEach","load","evaluate"];
+ for(var i in dojo){
+ safeCalls.push(i); // add the safe dojo functions to as available global top level functions
+ imports.push("var " + i + "=dojo." + i); // add to the list of imports
+ }
+ // open the dojo namespace (namespaces are pretty silly in an environment where you can't set globals)
+ eval(imports.join(";"));
+ function get(obj,prop) {
+ // basic access by index function
+ prop = '' + prop;
+ if(dojox.secure.badProps.test(prop)) {
+ throw new Error("bad property access");
+ }
+ if(obj.__get__) {
+ return obj.__get__(prop);
+ }
+ return obj[prop];
+ }
+ function set(obj,prop,value) {
+ // basic set by index function
+ prop = '' + prop;
+ get(obj,prop); // test it
+ if(obj.__set) {
+ return obj.__set(prop);
+ }
+ obj[prop] = value;
+ return value;
+ }
+ function forEach(obj,fun) {
+ // short syntax iterator function
+ if(typeof fun != "function"){
+ throw new TypeError();
+ }
+ if("length" in obj) {
+ // do arrays the fast way
+ if(obj.__get__) {
+ // use the catch getter
+ var len = obj.__get__('length');
+ for (var i = 0; i < len; i++) {
+ if(i in obj) {
+ fun.call(obj, obj.__get__(i), i, obj);
+ }
+ }
+ }
+ else {
+ // fast
+ len = obj.length;
+ for (i = 0; i < len; i++) {
+ if(i in obj) {
+ fun.call(obj, obj[i], i, obj);
+ }
+ }
+ }
+ }
+ else {
+ // for each an object
+ for (i in obj) {
+ fun.call(obj, get(obj,i), i, obj);
+ }
+ }
+ }
+ function Class(/*Function*/superclass, /*Object*/properties, /*Object*/classProperties) {
+ // summary:
+ // A safe class constructor
+ //
+ // superclass:
+ // There may be zero or more superclass arguments. The constructed class
+ // will inherit from any provided superclasses, protypically from the first,
+ // via mixin for the subsequent. Later arguments
+ // will override properties/methods from earlier arguments
+ //
+ // properties:
+ // The constructed
+ // "class" will also have the methods/properties defined in this argument.
+ // These methods may utilize the <em>this</em> operator, and they
+ // are only the code that has access to <em>this</em>. Inner functions
+ // are also prohibited from using <em>this</em>.
+ //
+ // If no superclasses are provided, this object will be the prototype of the
+ // constructed class (no copying
+ // will be done). Consequently you can "beget" by calling new (Class(obj)).
+ // All methods are "bound", each call results in |this| safety checking call.
+ //
+ // classProperties:
+ // This properties will be copied to the new class function.
+ //
+ // Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
+ // they are completely unsecure. This class constructor is conceptually based on declare
+ // but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
+ //
+ // example:
+ // | var Car = Class({drive:function(speed) { ... } ); // create a Car class with a "drive" method
+ // | var FastCar = Class(Car,{driveFast: function(speed) { return this.drive(2 * speed); } }); // create a FastCar that extends Car
+ // | var fastCar = new FastCar; // instantiate
+ // | fastCar.driveFast(50); // call a method
+ // | var driveFast = fastCar.driveFast;
+ // | var driveFast(50); // this will throw an error, the method can be used with an object that is not an instance of FastCar
+ var proto,superConstructor,ourConstructor;
+ var arg;
+ for (var i = 0, l = arguments.length; typeof (arg = arguments[i]) == 'function' && i < l; i++) {
+ // go through each superclass argument
+ if(proto) { // we have a prototype now, we must mixin now
+ mixin(proto,arg.prototype);
+ }
+ else {
+ // this is the first argument, so we can define the prototype ourselves
+ // link up the prototype chain to the superclass's prototype, so we are a subtype
+ superConstructor = arg;
+ var F = function() {};
+ F.prototype = arg.prototype;
+ proto = new F;
+ }
+ }
+
+ if(arg) { // the next object should be the properties
+ // apply binding checking on all the functions
+ for (var j in arg) {
+ // TODO: check on non-enumerables?
+ var value = arg[j];
+ if(typeof value == 'function') {
+ arg[j] = function() {
+ if(this instanceof Class){
+ return arguments.callee.__rawMethod__.apply(this,arguments);
+ }
+ throw new Error("Method called on wrong object");
+ };
+ arg[j].__rawMethod__ = value; // may want to use this for reconstruction and toString,valueOf
+ }
+ }
+ if(arg.hasOwnProperty('constructor')) {
+ ourConstructor = arg.constructor;
+ }
+ }
+ proto = proto ? mixin(proto,arg) : arg; // if there is no proto yet, we can use the provided object
+ function Class() {
+ // the super class may not have been constructed using the same technique, we will just call the constructor
+ if(superConstructor){
+ superConstructor.apply(this,arguments);
+ }
+ if(ourConstructor){
+ ourConstructor.apply(this,arguments);
+ }
+ }
+ mixin(Class,arguments[i]); // the optional second object adds properties to the class
+ proto.constructor = Class;
+ Class.prototype = proto;
+ return Class;
+ }
+ function checkString(func){
+ if(typeof func != 'function') {
+ throw new Error("String is not allowed in setTimeout/setInterval");
+ }
+ }
+ function setTimeout(func,time) {
+ // sandboxed setTimeout
+ checkString(func);
+ return oldTimeout(func,time);
+ }
+ function setInterval(func,time) {
+ // sandboxed setInterval
+ checkString(func);
+ return oldInterval(func,time);
+ }
+ function evaluate(script){
+ // sandboxed eval
+ return wrap.evaluate(script);
+ }
+ var load = wrap.load = function(url){
+ // provides a loader function for the sandbox
+ if (url.match(/^[\w\s]*:/)){
+ throw new Error("Access denied to cross-site requests");
+ }
+ return xhrGet({url:(new dojo._Url(wrap.rootUrl,url))+'',secure:true});
+ }
+ wrap.evaluate = function(script){
+ //if(!alreadyValidated) {
+ dojox.secure.capability.validate(script,safeCalls, // the safe dojo library and standard operators
+ {document:1,element:1}); // these are secured DOM starting points
+
+ //}
+ if(script.match(/^\s*[\[\{]/)) {
+ var result = eval('(' + script + ')');
+ // TODO: call render on result?
+ }
+ else {
+ eval(script);
+ }
+ //eval('wrap.evaluate=('+arguments.callee.toString()+')'); // yeah, recursive scoping;
+ };
+ return /*===== dojo.declare("dojox.secure.__Sandbox", null, =====*/ { // dojox.secure.__Sandbox
+ loadJS : function(url){
+ // summary:
+ // Loads the script from the given URL using XHR (assuming
+ // a plugin system is in place for cross-site requests) within the sandbox
+ //
+ // url:
+ // The url of the script to load
+ wrap.rootUrl = url;
+ return xhrGet({url:url,secure:true}).addCallback(function(result) {
+ evaluate(result,element /*If we get the results with a secure proxy, we would call put true here */);
+ });
+ },
+ loadHTML : function(url){
+ // summary:
+ // Loads the web page from the provided URL using XHR (assuming the
+ // plugin system is in place) within the sandbox. All scripts within the web
+ // page will also be sandboxed.
+ //
+ // url:
+ // The url of the web page to load
+
+ wrap.rootUrl = url;
+ return xhrGet({url:url,secure:true}).addCallback(function(result){
+ element.innerHTML = result;
+ });
+ },
+ evaluate : function(script){
+ // summary:
+ // Evaluates the given script within the sandbox
+ //
+ // script:
+ // The JavaScript text to evaluate
+ return wrap.evaluate(script);
+ }
+ // TODO: could add something for pre-validated scripts
+ }/*===== ) =====*/;
+ };
+})();
+dojox.secure._safeDojoFunctions = function(element,wrap) {
+ // Creates a safe subset of Dojo core library
+ var safeFunctions = ["mixin","require","isString","isArray","isFunction","isObject","isArrayLike","isAlien",
+ "hitch","delegate","partial","trim","disconnect","subscribe","unsubscribe","Deferred","toJson","style","attr"];
+ //var domFunctions = ["clone","byId"];
+ var doc = element.ownerDocument;
+ var unwrap = dojox.secure.unwrap;
+ dojo.NodeList.prototype.addContent.safetyCheck = function(content){
+ wrap.safeHTML(content);
+ };
+ dojo.NodeList.prototype.style.safetyCheck = function(name,value){
+ if(name=='behavior'){
+ throw new Error("Can not set behavior");
+ }
+ wrap.safeCSS(value);
+ };
+ dojo.NodeList.prototype.attr.safetyCheck = function(name,value){
+ if (value && (name == 'src' || name == 'href' || name=='style')){
+ throw new Error("Illegal to set " + name);
+ }
+ };
+ var safe = {
+ query : function(query,root) {
+ return wrap(dojo.query(query,unwrap(root || element))); // wrap the NodeList
+ },
+ connect: function(el,event) {
+ var obj = el;
+ arguments[0] = unwrap(el);
+ if(obj!=arguments[0] && event.substring(0,2) != 'on'){
+ // it is probably an element, and it doesn't look like an event handler, probably not safe
+ throw new Error("Invalid event name for element");
+ }
+ return dojo.connect.apply(dojo,arguments);
+ },
+ body : function() {
+ return element;
+ },
+ byId : function(id) {
+ return element.ownerDocument.getElementById(id); // use the safe document
+ },
+ fromJson : function(str) {
+ // make sure it is safe before passing it to the unsafe dojo.fromJson
+ dojox.secure.capability.validate(str,[],{});
+ return dojo.fromJson(str);
+ }
+ };
+ for (var i = 0; i < safeFunctions.length; i++) {
+ safe[safeFunctions[i]] = dojo[safeFunctions[i]];
+ }
+ return safe;
+};
+
+
+});