Tell HN: How to keep CA Security Suite from breaking your app
Hello HN:

I've been lurking for a long time but tonight I discovered interesting that I thought I should share.

I run a large site with lots of users, and we occasionally get mysterious bug reports about things just plain not working. We got one of these a couple days ago so I decided I'd try to get to the bottom of it. I got on the phone with this user and spent 45 minutes trying to figure out the problem. She had the latest firefox and a 6-month-old computer, so that checked out. Her other home computer had the same problem. She also had CA Security Suite installed, which I understand is reasonably popular (approx ~10% market share). She had gotten it bundled free with her RoadRunner ISP. When she turned off its firewall, the site worked, so the firewall was doing something my app didn't like. I asked her to open her firefox error console and she found errors like this:

http://qdaq.com/zzR.png

Ok, strange. I then asked her to open the file causing this error, which was at 127.0.0.1:37935/xpopup.js -- and had her email me the code. CA Security Suite is injecting some JS into the page (which is bad, yes, but not fatal). See if you can spot the problem in this js code:

http://pastie.org/801433

They're remapping the window.open, window.setTimeout, and window.setInterval to their "safe" versions of the code. Their "safe" version wraps the original setInterval() ("secretly" remembered as _orig_windowSetInterval) with some popup blocking code. It's all rather clever, and could even work transparently (apart from blocking your popups) if not for a code error in both _safe_setTimeout and _safe_setInterval:

function _safe_setInterval( sCode, iMilliSeconds )
{
// first block window.open -> execute the code -> unblock window.open
return (_orig_windowSetInterval("_block_windowOpen(); " + sCode + "; _unblock_windowOpen();", iMilliSeconds ));
}

They use the "eval" mode of setTimeout and setInterval, to which you pass a string. They rely on the idea that whatever function you used setInterval() for will work when it's been toString()ed. For example, setTimeout(function() { alert('test'); }, 100); will work just fine because its toString() value will work. But any function with bound properties will break because toString() will lose them. In my case, it was any function on which I used bind() or similar in Mootools, included default mootools stuff like style tweening. I would imagine JQuery would be similarly affected, though I don't use it. Thus, anything that relied on css fade-ins or anything else with timers was broken.

Fortunately, they made it easy to circumvent. Here's how I fixed it.

function undoBrokenBlockers() {
if (typeof _orig_windowOpen != 'undefined') {
window.open = _orig_windowOpen;
window.setTimeout = _orig_windowSetTimeout;
window.setInterval = _orig_windowSetInterval;
}
}
undoBrokenBlockers();

...with another call to that code onDOMReady (I'm not sure where they insert their script tag in html).

SO, I would recommend thinking about adding this code to your site, because you may have users who are broken right now as well.

After figuring all this out, I googled it and found someone who had reported it to CA four months ago: http://homeofficeforum.ca.com/homeofficeforum/showthread.php?t=5365 ... Who knows when they'll fix it.

moral: be careful when you mess with JS internals! Or don't mess at all!