Looking in the mirror: 2012 numbers, 2013 goals

man in the mirrorAs I did a year ago for 2011, here I am looking in the mirror at my 2012 numbers and 2013 goals:

  1. This blog:
    • 130 blogposts (78 “real” posts and 52 aggregated lifestream-events)
    • 109285 pageviews, the most popular individual article being 5 tips to tackle the problem with iframes (8622 views). Off all new 2012 blogposts, Fix Samsung ICS Exchange connection errors was read most with 5727 views.
    • 294 comments (including trackbacks and my own replies)
    • Main goal for 2013: carry on, I guess? Maybe some more personal posts in Dutch. I’ve always loved to write in my native language, but it can be pretty time-consuming as I tend to rewrite a text multiple times before I’m OK with wording and flow (which I’m not as sensitive to in my non-native English).
  2. WP YouTube Lyte, my WordPress plugin to do “lazy load YouTube embedding”, is doing really well:
    • 9 minor and 2 major releases including the big 1.0.0 milestone
    • 66286 downloads (passing the 100.000 downloads mark in July)
    • Main goal for 2013 and long overdue; responsiveness but also even better performance (less reliance on JavaScript to do heavy lifting, using less http-requests).
    • Moreover, I was honored to see Yoast’s Video SEO plugin has support for WP YouTube Lyte and equally proud to be able to decline a commercial proposal to have my plugin add a link next to each and every LYTE player.
  3. WP DoNotTrack 2012 proved a fruitful year for my 3rd party tracking filtering plugin:

2012 was also the year that I got to know Drupal & Acquia a lot better, the year my lovely daughter learned how to read, the year I grew scared of Europe’s economical & Belgium’s political future, the year I saw Radiohead live and the year I finally learned how to fly.

Jetpack Notifications puts Quantcast tracking in your WordPress Admin

WP DoNotTrack user Marco Donati asked why the plugin did not stop Quantcast from being included in the WordPress admin pages. After some research (with the kind assistance of Marco), I discovered not one but two problems;
WP DoNotTrack relies on “output buffering” in WordPress to filter/ modify the HTML when in “Forced (default)” or “SuperClean” mode. Apparently WordPress does not use output buffering in the admin-pages, so WP DoNotTrack did not get triggered. My bad! I’ve updated the code to fallback to “Normal” mode when in admin and will push out a new version with this fix soon.
But then it got slightly ugly; even with this fix in place, the Quantcast-tracker kept on appearing! It was being called from within an iFrame, outside the reach of WP DoNotTrack. The culprit turned out to be the brand new “Jetpack Notifications” feature which -as most of Jetpack- is activated by default. As from Jetpack 1.9, you’ll see a small icon next to the greeting text on the right side of the admin-bar. When you click that icon a drop-down appears which contains the iFrame and the tracking code. To disable, in “Notifications” click on “Learn more” to reveal the “Disable”-button. Click that one and the icon, iFrame and tracker code are gone. Good riddance!
My advice to Jetpack users; explicitly disable any feature you do not use. Jetpack might offer some nice functionality, but of that is available in other plugins as well and being tied in that heavily into wordpress.com does come at a price. Moreover it seems there are some security concerns; as an user with author permissions I had access to the Jetpack overview page and I was able to activate the “Jetpack Comments” feature on Marco’s blog, but I couldn’t disable it. Call me a paranoid security-zealot, but non-administrator users should not really be able to do that, should they?

Content Security Policy; Great! or Wait?

A couple of days ago I had another look at Content Security Policy, a technology that allows a site to tell a browser resources are allowed to be loaded to protect against XSS and some other types of web application vulnerabilities. CSP was originally devised by the Firefoxians, but is in the process of being standardized by the W3C with support in Firefox, Chrome, Safari and even the upcoming Internet Explorer 10.
Great!
The functionality offered by CSP (blocking requests that are not allowed) is pretty close to what WP DoNotTrack tries to do, so I decided I’d try to integrate CSP in my plugin, based on the following assumptions:

  • CSP-mode will only work for WP DoNotTrack if it is configured to use a whitelist
  • As most WordPress+plugins installations are bound to have pages with at least inline JavaScript and/or style, I have to add “unsafe-inline” to allow those to continue to work (which indeed limits the level of protection against XSS-attacks)
  • Given that a lot (most?) WordPress installations implement WP Super Cache of W3 Total Cache, it will -at least in a first stage- only kick in if WP  DoNotTrack is configured to filter unconditionally
  • Ideally the JavaScript-based component of WP DoNotTrack would “see” that CSP was activated and would not perform those nifty JavaScript AOP trickery

The “proof of concept”-quality code I ended up adding to wp-donottrack.php was pretty simple:

function wp_donottrack_csp() {
 global $listmode;
 if ($listmode==="1") {
  $whitelist=wp_donottrack_getWhiteList(true);
  $csp="default-src 'self' 'unsafe-inline'";
  if (is_array($whitelist)) {
   foreach ($whitelist as $white) {
    $csp.=" *.".$white;
   }
  }
  header("X-Content-Security-Policy: " . $csp); //FF & MSIE10
  header("Content-Security-Policy: ". $csp); //new standard
  header("X-WebKit-CSP: " . $csp); //chrome & safari
 }
}
add_action('init', 'wp_donottrack_csp', 10, 0);

Wait?
With this code on my testblog I started playing around in a couple of browsers. Based on that experience I found the following limitations:

So in this particular context (and specifically the absolute need for “unsafe-inline”), I’ve decided to hold off implementing CSP (I might implement iFrame sandboxing as support for that is coming with IE10 and will probably also land in Firefox 17). But if you have full control over a particular website or -application (meaning you can remove all inline JavaScript and CSS and all instances of evals in insourced JavaScript) and you want to harden your installation to stop cross-site scripting, you really should start thinking about implementing CSP (as Twitter seems to have done already)!

WP DoNotTrack: user opt-out for your Cookie Law pleasure

It was long overdue, but I finally came around to releasing version 0.8 of WP DoNotTrack. The main feature to warrant the bump in the version-number, is the addition of conditional filtering based on user opt-out.
There is no opt-out UI in the plugin, but it hooks in to “Civic Cookie Control“, a JavaScript-based widget with a nice and customizable UI, which allows your customers to consent to cookies or to opt-out of them. When on WordPress, you can easily enable and configure Civic Cookie Control by installing the Cookie Control WordPress plugin.
If you’d prefer to do without Cookie Control, you can add your solution for users to opt in or out and set a cookie “dont_track_me” with value “1”, which will trigger conditional filtering as well. A very, very basic implementation could be to add something along these lines in the head-section of your site (in header.php of your template):

var r=confirm("Click \"OK\" for the full experience or \"Cancel\" to disallow 3rd party sites to store cookies on your computer.");
if (r==true) {
document.cookie="dont_track_me=0;";
} else {
document.cookie="dont_track_me=1;";
}

The other features of 0.8 from the Changelog:

  • new: “forced” mode now default
  • bugfix: re-introduced the bugfix for whitelist mode that was rollbacked in 0.7.2 (and a bug in that bugfix was the reason for 0.8.1, actually)
  • bugfix: conflict with prototype which caused wysiwyg editing of Wysija newsletter templates to break

Join the Internet Defense League

Member of The Internet Defense LeagueYesterday I added a notification bar to this blog which invites visitors to join the Internet Defense League.
The notification bar is one of the several ways to participate with your own site or blog. I really liked the modal version better but that one seemed a tad too disruptive (I’m not 100% sure visitors would immediately understand this being an overlay with the actual blogpost underneath) and based on some tests on webpagetest.org (after adding internetdefenseleague.org and internetdefenseleague.s3.amazonaws.com to my WP DoNotTrack whitelist) it turned out to be significantly slower as well. The notification-bar variant has a more limited impact on page load time; only one extra 4.9KB request before document complete and a total of 5 requests at 14.1KB, which is … acceptable for this performance-nut.
So if you, like me, believe that we as internet-users should unite to take action against any law that goes against our interest (think SOPA, PIPA, ACTA, HADOPI, …), then joining the Internet Defense League might be a good idea.

Simple HTML DOM Parser not that simple

Notwithstanding the name, using PHP Simple HTML DOM Parser isn’t always simple. While working on some issues with WP DoNotTrack‘s SuperClean mode, I encountered these two quirks:

  1. By default Simple HTML DOM removes linebreaks. That means that when you write the modified DOM back to a string for outputting, some (sloppy) JavaScript is bound to break. The solution: pass extra arguments to the DOM-creating functions, as “documented” in the Simple HMTL DOM’s source code. For str_get_html it reads:
    function str_get_html($str, $lowercase=true, $forceTagsClosed=true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT)
    

    Set the 5th argument to false to tell the parser not to remove “\r\n”‘s.

  2. Simple HTML DOM is very liberal. It is so liberal, in fact, that it will try to make a DOM out of whatever you throw at it, without even blinking. Until you try to find elements using “find” on the DOM Object, that is, because at that point you might get a “Fatal error: Call to a member function find() on a non-object“-error thrown back at you. You can avoid that nastiness by checking the object for the existence of the find-method and, while you’re at it, also check if there is a HTML-element in the DOM:
    $html = file_get_html('http://url.to/filename.html');
    // first check if $html->find exists
    if (method_exists($html,"find")) {
         // then check if the html element exists to avoid trying to parse non-html
         if ($html->find('html')) {
              // and only then start searching (and manipulating) the dom
         }
    }

So that’s how to put the simple back into PHP Simple HTML DOM Parser. Until the next quirk comes up, because that’s what parsing HTML is all about after all, no?

WP DoNotTrack 0.7.0: SuperClean and EU Cookie Law

Last night I released WP DoNotTrack version 0.7.0, which adds a new filtering mode called SuperClean. Whereas the previous version only acted on elements added to the DOM, SuperClean now also allows you to filter the base HTML of your pages. To do this, SuperClean uses the PHP output buffer to catch the full HTML before it’s being sent to the browser.  That HTML is then parsed with PHP Simple HTML DOM Parser and based on your black- or whitelist the filtering is applied (SuperClean + whitelist = running a very tight ship, really). Currently SuperClean is not available if you have configured WP DoNotTrack to only stop tracking for people who have set the DoNotTrack-flag in their browser.
While we’re on the subject of conditional filtering; I’ve updated the code that checks for the DoNotTrack-flag to work around differences in browser implementations. Conditional filtering is pretty important, as it can help websites to comply with the (for now UK-only) “EU Cookie Law” which requires websites to ask their visitors for explicit consent prior to setting cookies. With WP DoNotTrack you can have your cookie and eat it too; you have your existing tracking scripts for users who give consent, while still being able to serve a “clean” website for users who enabled DoNotTrack in their browser. Given the fact that similar laws will be coming to a EU-country near you, conditional filtering is something I’ll be looking into further, so any feedback on the current implementation is more than welcome!

Bug and feedback driven development

I’m not a developer, I’m just a random guy who was lucky enough to be around when the web started to happen, back in the nineties. And over the years I might have learned a bit about web development, but still I’m not a real developer. And yet, there I am with two WordPress plugins, fiddling with PHP and JavaScript. I’ll let you in on what’s not really a secret; I’ve made some ridiculous mistakes while coding those plugins. Trial and error, you know. Testing, fixing, releasing and getting feedback. Especially getting feedback!

Real users telling me it doesn’t work, asking for extra features or making proposals to make it better overall, that what I thrive on. The latest example; JavaScript namespaces. Not being a developer means that I know as much about coding patterns as I know about cows. I just hit the keyboard real hard and hope the browser understands what I throw at it. Until a good friend told me to use JavaScript namespaces, to avoid conflicts with other people’s JavaScript. And a week later someone wrote my software just didn’t work any more and I had to start digging and found a JavaScript conflict that was introduced with a new version of AddThis

And those are the moments one grows, as a developer; you start searching for information about scope, anonymous functions and namespaces. You try, it doesn’t work and you dig some deeper, until you stumble on a great question and answer on Stack Overflow with a link to a very detailed article about JavaScript coding patterns. So you go back into ‘vi’ and start changing the code once again and than all of a sudden you have a working version, which your Polish user confirms fixes the problem and you learned a lot while bugfixing.
So kudo’s to all you guys & girls for the great feedback, you rock! Here’s WP YouTube Lyte version 1.1.3 to thank you.

WP DoNotTrack 0.6.0 and beyond

I finally found some time to continue to work my other WordPress plugin. WP DoNotTrack checks for elements being added to the DOM by JavaScript to stop 3rd party tracking by some of the major plugins or themes.

Version 0.6.0, which I released last week, features a new “forced” option. This mode aims to provide better compatibility with JavaScript-optimizing plugins such as Autoptimize and W3 Total Cache by adding the relevant code only after those optimizers have done their job, using the output buffer. There will probably be a 0.6.1 today or tomorrow, to solve a small problem with mixed HTTP/HTTPS requests on the admin-page while in HTTPS. The output buffer sure is a powerful thing and for version 0.7.0, I’ll build on that to optionally filter the full HTML (with PHP Simple HTML DOM Parser) to stop unwanted requests for images, scripts or iFrames in there.

Do contact me if you found a bug, if you have questions or if you’d like specific feature to be added, I tend to rely heavily on user feedback to improve my plugins! And if you’re happy with how it works, drop by on the WP DoNotTrack-page on wordpress.org to rate it and/ or to confirm it works with your version of WordPress!

Iframe sandboxing support coming soonish

Did you know you can limit the damage an iframe can do by adding the “sandbox” attribute? And that you can add a value to that attribute to loosen your grip if you choose to do so?
I remember reading about this a couple of years ago or so, but forgot as  support for this html5 spec was limited to Chrome (Apple added support in Safari as well). But while investigating a problem a WP DoNotTrack-user was facing, I re-discovered iframe sandboxing (it effectively stopped the javascript-based tracking inside the iframe) and noticed that support for it is to be included in Internet Explorer 10 and that Mozilla is finally working on an implementation as well.
So yeah, the option to sandbox iframe’s pointing to blacklisted (or non-whitelisted) hostnames will probably be in a future version of WP DoNotTrack. Stay tuned!