I screwed up. Big time.
Not just with Adblock Plus users but with the Mozilla community at large.
I did something extremely wrong, which I will regret forever.
I abused the power and wasted the enormous trust capital gained by the NoScript add-on through the years to prevent Adblock Plus from blocking stuff on four internet domains of mine, without asking an explicit preemptive user consent.
This is absolutely inexcusable. Something I would never conceive again for the life of me.
Please let me apologize first, then briefly explain what happened from a slightly different point of view than Wladimir Palant's, then apologize again.
You may ask why it took me so long to post something about the infamous Adblock Plus whitelisting incident here.
I've been quite busy all Friday night up to 11 AM of Saturday, apologizing with NoScript users one by one through facts, by hurrying out the 18.104.22.168 update which automatically removes any Adblock Plus related configuration with no questions asked. Then, after a couple hours of sleeping, I tried to answer some questions left open in the public forum thread where discussion about my admittedly stealthy and borderline reaction to EasyList's attack on my web sites had been politely going on and leading to an acceptable solution, before Wladimir decided to invite Reddit, Slashdot and Digg to the party. Furthermore I'm still coping with a huge backlog of email messages: I've never left a NoScript-related email unanswered, and the fact some are (legitimately) less kind than usual now is not a good reason to give up.
The development of NoScript is sustained both by donations and advertisements published on a few related web sites in four domains (noscript.net, flashgot.net, informaction.com and hackademix.net). I've never tried to hide the latter revenue stream, as you can see in this very old FAQ about NoScript's default whitelist, which Wladimir loves to rehash every time he has a chance to depict me as a hypocrite driven by greed. What I really think is that while ads are important to support NoScript development, users' ability to block anything displeasing them is much more important. Deciding what is their prerogative.
Adblock Plus is meant to block ads, but it doesn't block anything by default. In facts, according to its own author, it's meant to block obnoxious ads, implying it's up to users to choose which ads are acceptable and which deserve to be annihilated. I couldn't agree more with this "user choice is the king" principle, even though I recently abdicated to it myself by doing the odious thing we're talking about here.
When users install Adblock Plus, though, they are encouraged at subscribing so called filtersets, which choose for them what's good and what's bad. EasyList is the most popular of these filterset subscriptions. When something is blocked by a filterset like EasyList, stuff just disappears from the page without notice. There's a "blockable items panel" you can open to check what's going on, but you never get any notification. This is still good as long as either what disappears has been a choice of yours, or the filter subscription did a perfect job guessing what can interest you and what cannot. Otherwise you don't even get to know something is missing and why.
For some time my sites used a publicly known Adblock Plus bug to work-around EasyList's generic filters against Adsense and display their Google Ads boxes, even though Adblock Plus users could still easily block them if they wished to by adding their own custom filter. Furthermore, NoScript users could even more easily remove those ads all at once by just forbidding googlesyndication.com. In other words, this "trick", as Wladimir calls it, put the choice back in users' hands.
About 2 weeks ago Wladimir decided this had been going on long enough: the Google boxes supporting NoScript had to be shut down for good. So, rather than fixing his Adblock Plus bug, he asked Ares2 (the new Easylist maintainer, after Rick752 passed away) to nuke them by specifically targeting NoScript sites. When I noticed this, I thought it was Ares2's own initiative (new person, new mentality), but Wladimir finally clarified this point in his Friday's post:
I suggested that EasyList should be extended by a filter to block ads specifically on NoScriptâ€™s domains. This finally happened two weeks ago.
All this time I couldn't imagine that he had been behind Ares2 from the start, otherwise I would have just asked Wladimir why he was sniping my sites, rather than coding a more reliable Adblock Plus version. Instead I began tracking EasyList changes and counterreacting. Of course Ares2 didn't stop, nor I did, so we engaged in an escalation through more than 30 EasyList updates (even 4-5 per day) specifically aimed at my sites, with filters like these (yes, stacked all together):
If you've got some familiarity with Adblock Plus filters, you'll notice any standard web technology beyond basic HTML/CSS (scripting, frames, AJAX) was completely disabled.
They got to the point where users could no longer even see the regular links to install NoScript or FlashGot.
Crossing the Dirty Line
As you can imagine I was quite pissed off then. Blocking my ads was one thing (it's EasyList's job, after all -- I was just surprised of being so popular to deserve such a dedicated treatment), but disabling any dynamic feature and destroying essential site functionality such as install and development build links was a different story.
Mind you, I'm not trying to justify my actions here. They are unjustifiable, and anger is hardly a justification for anything, but since I've been accused of having acted out of pure greed I need to clarify that it was not my prevalent feeling at all, even though I won't hide that EasyList's crusade had actually cut the NoScript development funding by a substantial amount.
So I had this crazy idea of retaliating against EasyList "from the inside", and in my blindness I did not grasp that I was really retaliating against my own users and the Mozilla community at large. Even worse, my hacker attitude led me to dig directly in the low level Adblock Plus internals where filters are enforced, assuming there was no "interesting" API to hook (more on this later). Therefore, while I was about to release a long awaited feature (bookmark-based synchronization), I took 10 minutes to add a small piece of code (mrd.js) which implemented my own "hand made" whitelist, working around those filters targeted to my sites but leaving the Adblock Plus functionality otherwise intact.
I included also an about:config preference (noscript.mrd) to deactivate this "feature": it was meant for an user interface to follow up, but I've been foolish enough to defer its implementation and perform a stealthy "test drive" instead, while trying to figure out the best way to go public afterward.
When I pushed the "release" button, my soul was already damned.
Digression 1: AMO
Some of the thousands who commented on this issue so far argued that AMO should have reviewed the code or at least test the package before releasing it to the public. This did not happen, and I want to clarify it's not AMO's fault. Nobody from AMO even saw the release passing by, because the extension was considered "trusted", i.e. not needing any approval for exiting the so called "Sandbox".
This kind of "trust" is not related to malware, but to quality assurance: if an extension demonstrates to be tested enough (e.g. because it has already many beta testers) it gets approved automatically, alleviating AMO editors' huge workload. Either way, with my insanity I betrayed this "trust" as well and put AMO in an awkward position.
I apologize with to the AMO staff people, whose hard and continuous work constantly improves the Mozilla ecosystem, and with all the other add-on developers: now I realize that the general security of the Mozilla extensibility system is being questioned because of this incident. Believe me: I didn't even considered such a fallout as a remote risk. I've been too much enraged and stupid to think about all these consequences. Please forgive me.
Digression 2: Obfuscated(!)
When I investigated this issue I couldnâ€™t believe my eyes. NoScript was extended by a piece of obfuscated (!) code to specifically target Adblock Plus and disable parts of its functionality.
There are several parts of his post and comments who would need an accurate rebuttal, either because overstretched, subtly smearing, spreading FUD or just plainly false. But this post is about my sins, repent and begging forgiveness, so that will have to wait.
However the "obfuscation" argument deserves to be treated right now, because it's very pertinent to the facts we're discussing here and hinting about the real nature and extent of my intentions (while no way this is meant to mitigate the judgment on my actions). I already answered in the forum to direct questions about this so called obfuscation, but let me summarize here.
While writing readable code may not be my primary skill, the code Wladimir analyzed was hardly obfuscated, not at least in the traditional computer-related meaning of "making it unreadable to fellow coders": in facts it's even nicely indented, and identifiers (function and variable names) are concise but yet meaningful enough. Some data had been actually made harder to read (i.e. ABP's id and the CSS rules template for element unhiding) even though by a very simple and recognizable method (unicode hex encoding), not to target code reviewers (who would understand it at first spot, like Wladimir did) or users (who would not read it anyway): the quite self-evident recipients of this "obfuscation" were EasyList maintainers and Ares2 specifically. My (ingenuous and stupid) intent was checking how the system worked "live" but far from his eyes, and in the meanwhile searching for the best way to turn it into a public "feature", e.g. by building an user interface around the noscript.mrd preference.
NoScript's Black Friday
The rest of this story is quite well known and documented: while I was on a disconnected weekend trip, I took some time looking more broadly at Adblock Plus code, and I slapped my head when I found a public API meant to allow just that after all: adding external filtersets from another extension (it was meant for Filterset.G, apparently) and making them visible and easily manageable from Adblock Plus' own user interface. So when Wladimir contacted me with a friendly mail about my alleged malware, I offered using that API as a quick solution. He answered that it was OK by principle, but since NoScript was a security add-on users should have been asked and a prominent disclaimer about this "feature" be added on the AMO description. Since I had no problem with giving users all the information in the open, included detailed removal instructions (two clicks), but was concerned about the annoyance of a blocking nag box on startup, I replied
I'll inform users about the added whitelist filter both in the AMO description and on the landing release notes page [automatically shown after updates], where I'll provide them also with instructions to remove it.
He did not answer anymore, so I assumed he had no objections. And this was my second big mistake.
This "open" approach went in a beta (22.214.171.124) and then in a stable release (126.96.36.199). But almost immediately after releasing it, I realized that this was not enough and expressed my intention to add to NoScript an explicit startup prompt asking once forever if user wanted to keep/install or permanently remove (also retroactively) the filterlist. This was announced on friday morning (Italy time), and was planned to be done in 24-36 hours (on Saturday), but unfortunately 10 hours later was already too late. The email from an AMO representative, suggesting to add an opt-in dialog in the next version, found me (at 3 AM local time) already working like a night owl to hurry out NoScript 188.8.131.52 which implemented it retroactively (more than what AMO was actually asking for). At 7.05 AM I finally announced to him 184.108.40.206 was in the AMO Sandbox, waiting for approval. Unfortunately in the meantime too much stuff had already hit the proverbial fan, so he informed me that adding the opt-in dialog was not enough anymore (something I had been realizing myself while I was coding and my inbox kept growing with a bad smell):
We've given this some thought and came up with the following policy after internal discussion as well as discussion with the community:
From what we understand of your filterset install, your filter change is unrelated to the functionality of your add-on and will be rejected. I'm asking you to remove this functionality and retain the retroactive box. You can include a link to the filterset on your first run page but as far as in-extension functionality, we won't allow this on AMO. Please let me know your thoughts.
At that point my answer was immediate and almost relieved, because 220.127.116.11 was already available on my site, but 18.104.22.168 (with much more drastic cleanup measures) was already in my mind as the most honorable offer to make my users as a sign of repent:
I'm OK with removing the functionality.
If you don't mind, could you explain what exactly you mean by "retaining the retroactive box"? Could I just delete the filterset on startup, or I need to do something else?
Sorry to waste your time, but I'd want to be sure before creating other useless code at 7:34 AM after having spent all the night on this issue (for my fault, of course).
After receiving an enthusiastic OK on this resolution, I wrote the apology that every NoScript user (even those who didn't know about all this mess yet and/or had no Adblock Plus installed) was meant to read on automatic update page, dared a (painful) look at Slashdot, Reddit, Digg, NoScript's AMO page and my own forums, had a much needed shower, kissed my spouse and my child and finally headed to bed (about at 11AM) to sleep a couple of hours.
Saturday Night Fever
When I woke up, the sky was still falling (especially on AMO, where NoScript had received more ratings than in 4 full years of life). But I also noticed some unexpectedly encouraging email was coming in and, incredibly, donations were skyrocketing. Maybe the sincerity of my sorrow for this incident was arriving to someone. So I started multitasking between the forum and this very writing, and here we are.
Obviously there are still many things to do, but I desperately hope abandoning NoScript development is not among them.
One is this blog post, which I should finally be able to publish in minutes.
Another is setting up a publicly accessible code repository for my extensions, something I procrastinated too long but suddenly became a top openness priority.
Other ways to try regaining NoScript's user base's trust will probably come to my mind later, and any suggestion is welcome.
But back to the main topic of this post.
I beg you to accept my most sincere apologies and believe in my shame and contrition.
I know I've done something horrible, creating a scandal like the Mozilla community never had faced before and betraying the trust of many, many people.
Please help me to repair the damage I've caused with my errors.