Complexity is the enemy of security, so I find it best to implement a simple solution that you know is secure rather than attempting to come up with something more complicated that has possibly made something safe (but no one is quite sure until an exploit is found).
A safe way to do it is that you could use a HTML5 Sandbox to load a page hosting your script, then you do not need to be concerned about whether your RegEx can be bypassed.
You will need to host the page under a different domain than your main site (e.g. script.example.com
instead of www.example.com
). This will prevent any XSS attack if an attacker convinces a user to visit the page directly (outside of the sandbox).
You will need to enable scripts within the IFrame by using code like this:
<iframe src="http://script.example.com/projects/diediedie/" sandbox="allow-scripts" />
This will allow scripts, but in the case of an exploit being found to your RegEx, forms and navigation outside of the IFrame will be prevented. As it is on a different domain, your main site cannot be attacked via XSS.
The HTML5 Security Cheat Sheet guidance on OWASP states this is the purpose of the sandbox:
Use the sandbox attribute of an iframe for untrusted content
As you are allowing untrusted content to run via eval
(albeit "sanitised" via RegEx), this seems like an appropriate use of the sandboxed IFrame.
You should test whether sandbox is supported first, before rendering the IFrame:
<iframe src="/blank.htm" sandbox="allow-scripts" id="foo" />
var sandboxSupported = "sandbox" in document.createElement("iframe");
if (sandboxSupported) {
document.getElementById('foo').setAttribute('src', 'http://script.example.com/projects/diediedie/');
}
else
{
// Not safe to display IFrame
}
It is safer to do it this way by dynamically changing the src
rather than redirecting away if sandboxSupported
is false
because then the iframe will not accidentally be rendered if the redirect doesn't happen in time.
To enable this to work cross-domain (between script.example.com
and www.example.com
) you will need to use HTML5's Window.postMessage
functionality. This will enable secure communication between the IFrame and the outer window. Note that setting document.domain
is not secure as it will defeat the purpose of hosting the page on a separate domain in the first place.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…