{"version":3,"sources":["../index.js"],"names":["window","undefined","_cloneError","err","name","message","stack","_union","arr1","arr2","concat","filter","key","i","arr","indexOf","_isWindowFramed","isNotChildWindow","opener","hasWindowAncestors","top","parent","_isFrameElement","el","result","nodeType","test","nodeName","hasAttribute","getAttribute","setAttribute","_getFrame","errback","frameEl","frameElement","_getEffectiveScriptOrigin","effectiveScriptOrigin","document","domain","_defaultAllowancesMapForNullAllowances","forms","modals","orientationLock","pointerLock","popups","popupsToEscapeSandbox","presentation","sameOrigin","scripts","topNavigation","topNavigationByUserActivation","_createAllowancesMap","allowancesString","allowanceList","allowancesMap","replace","toLowerCase","split","_sandboxAllowancesMatch","sbAllowances1","sbAllowances2","allUsedKeys","len","prop","allMatched","Object","keys","length","hasOwnProperty","_analyzeSandboxing","sandboxAllowances","resandboxable","resandboxAllowances","resandboxLossless","sandboxed","unsandboxable","errors","sandboxErr","removeAttribute","SandBlaster","sb","this","_initialState","detect","_unsandboxState","_slice","Array","prototype","slice","frame","frameError","subResult","results","framed","crossOrigin","sandboxable","push","frameErrback","unsandbox","_current","_init","resandbox","sandbox","_currentAllowances","isLockingDown","sandboxAttr","forEach","allowance","sort","join","reload","attrs","newFrameEl","replacedFrameEl","parentNode","ownerDocument","call","attributes","map","item","value","createElement","replaceChild","sandblaster"],"mappings":"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","file":"sandblaster.min.js","sourcesContent":["(function(window, undefined) {\n\n\"use strict\";\n\n/********************\n * *\n * Utility code *\n * *\n ********************/\n\nvar _slice = Array.prototype.slice;\n\nfunction _cloneError(err) {\n // Some browsers and/or Error types do not need to clone correctly via\n // JSON serialization, so we may need to manually update the copy instead.\n //\n // This likely means that the Error instance's properties are:\n // (a) non-enumerable;\n // (b) prototypically inherited; or\n // (c) getter functions\n\n return {\n name: err.name,\n message: err.message,\n stack: err.stack\n };\n}\n\nfunction _union(arr1, arr2) {\n return (\n (arr1 || [])\n .concat(arr2 || [])\n .filter(function(key, i, arr) {\n return arr.indexOf(key) === i;\n })\n );\n}\n\nfunction _isWindowFramed() {\n /*jshint eqeqeq:false */\n // Cannot compare WindowProxy objects with ===/!==\n\n var isNotChildWindow = !window.opener,\n hasWindowAncestors = !!((window.top && window != window.top) || (window.parent && window != window.parent));\n return isNotChildWindow && hasWindowAncestors;\n}\n\nfunction _isFrameElement(el) {\n var result;\n try {\n result = (\n typeof el === \"object\" &&\n el !== null &&\n el.nodeType === 1 &&\n /^I?FRAME$/.test(el.nodeName || \"\") &&\n !!el.hasAttribute && !!el.getAttribute && !!el.setAttribute\n );\n }\n catch (err) {\n result = false;\n }\n return result;\n}\n\nfunction _getFrame(errback) {\n var frameEl;\n try {\n frameEl = window.frameElement;\n if (!_isFrameElement(frameEl)) {\n frameEl = null;\n }\n }\n catch (err) {\n frameEl = null;\n if (typeof errback === \"function\") {\n errback(_cloneError(err));\n }\n }\n return frameEl;\n}\n\nfunction _getEffectiveScriptOrigin(errback) {\n var effectiveScriptOrigin;\n try {\n effectiveScriptOrigin = document.domain || null;\n }\n catch (err) {\n effectiveScriptOrigin = null;\n if (typeof errback === \"function\") {\n errback(_cloneError(err));\n }\n }\n return effectiveScriptOrigin;\n}\n\nfunction _defaultAllowancesMapForNullAllowances() {\n return {\n forms: null,\n modals: null,\n orientationLock: null,\n pointerLock: null,\n popups: null,\n popupsToEscapeSandbox: null,\n presentation: null,\n sameOrigin: true,\n scripts: true,\n topNavigation: null,\n topNavigationByUserActivation: null\n };\n}\n\nfunction _createAllowancesMap(allowancesString) {\n var allowanceList,\n allowancesMap = null;\n\n if (allowancesString === null) {\n allowancesMap = _defaultAllowancesMapForNullAllowances();\n }\n else if (typeof allowancesString === \"string\") {\n allowanceList =\n allowancesString\n .replace(/^\\s+|\\s+$/g, \"\")\n .toLowerCase()\n .split(/\\s+/);\n\n allowancesMap = {\n forms: allowanceList.indexOf(\"allow-forms\") !== -1,\n modals: allowanceList.indexOf(\"allow-modals\") !== -1,\n orientationLock: allowanceList.indexOf(\"allow-orientation-lock\") !== -1,\n pointerLock: allowanceList.indexOf(\"allow-pointer-lock\") !== -1,\n popups: allowanceList.indexOf(\"allow-popups\") !== -1,\n popupsToEscapeSandbox: allowanceList.indexOf(\"allow-popups-to-escape-sandbox\") !== -1,\n presentation: allowanceList.indexOf(\"allow-presentation\") !== -1,\n sameOrigin: allowanceList.indexOf(\"allow-same-origin\") !== -1,\n scripts: allowanceList.indexOf(\"allow-scripts\") !== -1,\n topNavigation: allowanceList.indexOf(\"allow-top-navigation\") !== -1,\n topNavigationByUserActivation: allowanceList.indexOf(\"allow-top-navigation-by-user-activation\") !== -1\n };\n }\n\n return allowancesMap;\n}\n\nfunction _sandboxAllowancesMatch(sbAllowances1, sbAllowances2) {\n var allUsedKeys, i, len, prop,\n allMatched = false;\n\n if (\n sbAllowances1 && typeof sbAllowances1 === \"object\" &&\n sbAllowances2 && typeof sbAllowances2 === \"object\"\n ) {\n allUsedKeys = _union(Object.keys(sbAllowances1), Object.keys(sbAllowances2));\n\n allMatched = true;\n for (i = 0, len = allUsedKeys.length; i < len; i++) {\n prop = allUsedKeys[i];\n if (!(\n sbAllowances1.hasOwnProperty(prop) &&\n sbAllowances2.hasOwnProperty(prop) &&\n sbAllowances1[prop] === sbAllowances2[prop]\n )) {\n allMatched = false;\n break;\n }\n }\n }\n\n return allMatched;\n}\n\n\n/*********************\n * *\n * Analysis code *\n * *\n *********************/\n\nfunction _analyzeSandboxing(frameEl, errback) {\n /*jshint maxstatements:45 */\n\n //\n // An interesting note from: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe\n //\n // NOTE:\n // \"When the embedded document has the same origin as the main\n // page, it is strongly discouraged to use both allow-scripts\n // and allow-same-origin at the same time, as that allows the\n // embedded document to programmatically remove the sandbox\n // attribute. Although it is accepted, this case is no more\n // secure than not using the sandbox attribute.\"\n //\n // So... let's give that a try, too! >=D\n //\n var sandboxAllowances, resandboxable, resandboxAllowances, resandboxLossless,\n result = {\n sandboxed: undefined,\n sandboxAllowances: undefined,\n unsandboxable: undefined,\n resandboxable: undefined,\n errors: []\n };\n\n if (_isFrameElement(frameEl)) {\n\n // Is sandboxed?\n try {\n result.sandboxed = frameEl.hasAttribute(\"sandbox\");\n }\n catch (sandboxErr) {\n result.sandboxed = null;\n if (typeof errback === \"function\") {\n errback(sandboxErr);\n }\n }\n\n // Get sandbox configuration\n if (result.sandboxed) {\n try {\n sandboxAllowances = frameEl.getAttribute(\"sandbox\") || \"\";\n }\n catch (sandboxErr) {\n sandboxAllowances = null;\n if (typeof errback === \"function\") {\n errback(sandboxErr);\n }\n }\n }\n else if (result.sandboxed === null) {\n sandboxAllowances = null;\n }\n\n if (sandboxAllowances === null || typeof sandboxAllowances === \"string\") {\n result.sandboxAllowances =_createAllowancesMap(sandboxAllowances);\n }\n\n // Analyze desandboxability\n if (result.sandboxed) {\n try {\n frameEl.removeAttribute(\"sandbox\");\n result.unsandboxable = !frameEl.hasAttribute(\"sandbox\");\n }\n catch (sandboxErr) {\n result.unsandboxable = false;\n if (typeof errback === \"function\") {\n errback(sandboxErr);\n }\n }\n }\n\n // Analyze resandboxability\n if (result.unsandboxable && typeof sandboxAllowances === \"string\") {\n try {\n frameEl.setAttribute(\"sandbox\", sandboxAllowances);\n resandboxable = frameEl.hasAttribute(\"sandbox\");\n }\n catch (sandboxErr) {\n resandboxable = false;\n if (typeof errback === \"function\") {\n errback(sandboxErr);\n }\n }\n }\n\n // Get resandboxed configuration\n if (resandboxable && result.sandboxAllowances) {\n try {\n resandboxAllowances = frameEl.getAttribute(\"sandbox\") || \"\";\n }\n catch (sandboxErr) {\n resandboxAllowances = null;\n if (typeof errback === \"function\") {\n errback(sandboxErr);\n }\n }\n }\n else if (resandboxable === null) {\n resandboxAllowances = null;\n }\n\n if (resandboxAllowances === null || typeof resandboxAllowances === \"string\") {\n resandboxAllowances = _createAllowancesMap(resandboxAllowances);\n }\n\n // Analyze quality of resandboxability\n if (resandboxable) {\n resandboxLossless = null;\n\n if (result.sandboxAllowances && resandboxAllowances) {\n resandboxLossless = _sandboxAllowancesMatch(result.sandboxAllowances, resandboxAllowances);\n }\n }\n result.resandboxable = resandboxLossless;\n }\n\n return result;\n}\n\n\n/**\n * Underlying \"class\" for the sandblaster API.\n *\n * @constructor\n */\nfunction SandBlaster() {\n var sb = this;\n\n if (!(sb instanceof SandBlaster)) {\n return new SandBlaster();\n }\n\n sb._initialState = sb.detect();\n sb._unsandboxState = null;\n}\n\n\n/**\n * ???\n *\n * @returns Object detailing the current page's frame-related state and capabilities\n * @public\n */\nSandBlaster.prototype.detect = function sandblaster$detect() {\n var frame, frameError, subResult,\n results = {\n framed: false,\n crossOrigin: null,\n sandboxed: null,\n sandboxAllowances: undefined,\n unsandboxable: undefined,\n resandboxable: undefined,\n sandboxable: undefined,\n errors: []\n },\n errback = function(err) {\n results.errors.push(_cloneError(err));\n },\n frameErrback = function(err) {\n frameError = _cloneError(err);\n results.errors.push(frameError);\n };\n\n try {\n results.framed = _isWindowFramed();\n if (!results.framed) {\n results.crossOrigin = undefined;\n results.sandboxed = undefined;\n results.errors = undefined;\n }\n else {\n frame = _getFrame(frameErrback);\n\n if (frame != null) {\n results.crossOrigin = false;\n\n subResult = _analyzeSandboxing(frame, errback);\n results.sandboxed = subResult.sandboxed;\n results.sandboxAllowances = subResult.sandboxAllowances;\n results.unsandboxable = subResult.unsandboxable;\n results.resandboxable = subResult.resandboxable;\n }\n else {\n\n // IMPORTANT:\n // Firefox will return `frame == null` and NOT throw any Error for\n // cross-origin `frameElement` access:\n // https://bugzilla.mozilla.org/show_bug.cgi?id=868235\n\n // Set the most frequent default values\n results.crossOrigin = true;\n results.sandboxed = null;\n results.sandboxAllowances = {\n forms: null,\n modals: null,\n orientationLock: null,\n pointerLock: null,\n popups: null,\n popupsToEscapeSandbox: null,\n presentation: null,\n sameOrigin: null,\n scripts: true,\n topNavigation: null,\n topNavigationByUserActivation: null\n };\n results.unsandboxable = false;\n results.resandboxable = false;\n\n // `document.domain` has been rendered useless by sandboxing\n // without granting `allow-same-origin`\n if (_getEffectiveScriptOrigin(errback) === null) {\n results.sandboxed = true;\n results.sandboxAllowances.sameOrigin = false;\n }\n else if (frameError) {\n if (frameError.name !== \"SecurityError\") {\n // Retract previous value... we're not sure anymore!\n results.crossOrigin = null;\n }\n else if (/(^|[\\s\\(\\[@])sandbox(es|ed|ing|[\\s\\.,!\\)\\]@]|$)/.test(frameError.message.toLowerCase())) {\n results.sandboxed = true;\n results.sandboxAllowances.sameOrigin = true;\n }\n }\n }\n\n // Finally, do some analysis to see if we can authoritatively add sandboxing (e.g. if not sandboxed already)\n results.sandboxable = (\n results.resandboxable ||\n (\n results.framed === true &&\n results.crossOrigin === false &&\n (results.sandboxed === false || results.sandboxAllowances.sameOrigin)\n ) ||\n false\n );\n }\n }\n catch (err) {\n errback(err);\n }\n\n return results;\n};\n\n\n/*******************\n * *\n * Action code *\n * *\n *******************/\n\n/**\n * ???\n */\nSandBlaster.prototype.unsandbox = function sandblaster$unsandbox() {\n var _current, frameEl,\n result = false,\n sb = this,\n _init = sb._initialState;\n\n // If the page was never framed, bail out early because it will never change\n if (_init.framed === false) {\n result = true;\n }\n else if (_init.crossOrigin === false) {\n _current = sb.detect();\n result = _current.sandboxed === false;\n\n // Unsandbox it\n if (_current.sandboxed && _current.unsandboxable) {\n\n // Keep track of the state of the frame before unsandboxing for potential resandboxing later\n sb._unsandboxState = _current;\n\n frameEl = _getFrame(function(/* err */) { result = false; });\n if (frameEl) {\n try {\n frameEl.removeAttribute(\"sandbox\");\n result = !frameEl.hasAttribute(\"sandbox\");\n }\n catch (err) {\n result = false;\n }\n }\n }\n }\n\n return result;\n};\n\n\n/**\n * ???\n */\nSandBlaster.prototype.resandbox = function sandblaster$resandbox() {\n var result = false,\n sb = this;\n\n // If the page was unsandboxed, try to resandbox it\n if (sb._unsandboxState != null) {\n result = sb.sandbox(sb._unsandboxState.sandboxAllowances);\n }\n\n // If it succeeded, don't keep track of the previous unsandboxed state anymore\n if (result === true) {\n sb._unsandboxState = null;\n }\n\n return result;\n};\n\n\n/**\n * ???\n */\nSandBlaster.prototype.sandbox = function sandblaster$sandbox(sandboxAllowances) {\n var allowancesString, keys, _current, _currentAllowances, isLockingDown, frameEl, sandboxAttr,\n result = false,\n sb = this,\n _init = sb._initialState,\n allowanceList = [];\n\n if (\n sandboxAllowances && typeof sandboxAllowances === \"object\" &&\n _init.framed && _init.crossOrigin !== false\n ) {\n // Verify the state before continuing\n _current = sb.detect();\n\n // BUT also conduct some other live checks before attempting to sandbox it\n if (\n (_current.sandboxed === false && _current.sandboxable) ||\n (_current.sandboxed && _current.unsandboxable)\n ) {\n _currentAllowances = _current.sandboxAllowances;\n\n keys = _union(Object.keys(sandboxAllowances), Object.keys(_currentAllowances || {}));\n keys.forEach(function(allowance) {\n if (\n sandboxAllowances[allowance] === true ||\n (\n sandboxAllowances[allowance] == null &&\n _currentAllowances &&\n _currentAllowances[allowance] === true\n )\n ) {\n allowanceList.push(\"allow-\" + allowance.replace(/[A-Z]/g, \"-$1\").toLowerCase());\n }\n });\n\n if (allowanceList.length > 0 && (frameEl = _getFrame())) {\n isLockingDown = (\n allowanceList.indexOf(\"allow-same-origin\") === -1 ||\n allowanceList.indexOf(\"allow-scripts\") === -1\n );\n allowancesString = allowanceList.sort().join(\" \");\n\n try {\n // Add/update the sandbox\n frameEl.setAttribute(\"sandbox\", allowancesString);\n result = isLockingDown;\n }\n catch (err) {\n result = false;\n }\n\n // Get a fresh element reference (or `null`)\n if ((frameEl = _getFrame())) {\n // May throw a SecurityError now, depending on the new sandbox configuration\n try {\n sandboxAttr =\n (frameEl.getAttribute(\"sandbox\") || \"\")\n .replace(/^\\s+|\\s+$/g, \"\")\n .split(/\\s+/)\n .sort()\n .join(\" \");\n\n result =\n sandboxAttr === allowancesString ||\n (isLockingDown && (sandboxAttr === \"\" || _getEffectiveScriptOrigin() === null));\n }\n catch (err) {\n // May not be able to touch the sandbox anymore due to security lockdown and/or\n // script disabling (if it even lets this event loop iteration finish!?)\n result = isLockingDown;\n }\n }\n }\n }\n }\n\n return result;\n};\n\n\n/**\n * ???\n */\nSandBlaster.prototype.reload = function sandblaster$unsandboxAndReload() {\n var frameEl, attrs, newFrameEl, replacedFrameEl,\n result = false,\n sb = this,\n _init = sb._initialState;\n\n // If the page was never framed or was cross-origin, bail out early because it will never change\n if (_init.framed && _init.crossOrigin === false) {\n frameEl = _getFrame();\n if (frameEl) {\n try {\n if (frameEl.parentNode && frameEl.parentNode.ownerDocument) {\n attrs = _slice.call(frameEl.attributes).map(function(item) {\n return { name: item.name, value: item.value };\n });\n\n newFrameEl = frameEl.parentNode.ownerDocument.createElement(\"iframe\");\n attrs.forEach(function(item) {\n newFrameEl.setAttribute(item.name, item.value);\n });\n replacedFrameEl = frameEl.parentNode.replaceChild(newFrameEl, frameEl);\n result = frameEl === replacedFrameEl;\n }\n }\n catch (err) {\n result = false;\n }\n }\n }\n\n return result;\n};\n\n\n/**********************\n * *\n * Export the API *\n * *\n **********************/\n\nwindow.sandblaster = new SandBlaster();\n\n})(window);\n"]}