Gerade vor einer Stunde dachte ich noch, dass meine WordPress-Installation gehackt worden wäre. Mein WP-Dashboard zeigte unter anderem folgende merkwürdigen Bilder an:

unicorn aprilfools

Auch ließen sich keine Links anklicken. Der Blog war offenbar auch davon betroffen. Kurzerhand habe ich die Webseite für einige Minuten vom Netz genommen. Die Quelle der Bilder war www.cornify.com. Im Javascript-Quelltext konnte ich eine Variable mit dem Namen “pwned” ausmachen. Klarer Fall, dachte ich. Mein WordPress wurde gehackt.

Erste Versuche, herauszufinden, ob die aktuelle WordPress-Version eine schlimme Sicherheitslücke beinhaltete (ja, ich weiß, WordPress IST eine schlimme Sicherheitslücke), brachten aber nichts zutage, genauso wenig wie eine Suche nach etwaigen Unicorn-Hacks. Dass es jemand speziell auf meinen Blog abgesehen hatte, wollte ich aber ausschließen. Davon hätte niemand was, ist auch zu unbekannt.

Die Datenbank war völlig intakt, auch sonst war nichts beschädigt. Nur blöde Einhorn- bzw. Pony-Bilder. Also wahrscheinlich doch kein Hack, sonst wäre das Ergebnis sicher schlimmer gewesen. Eine weitere Google-Suche nach einem Ausdruck im Quelltext “show ponies on 1st click of a link” ließ mich auf der Webseite von Digitalnature landen, den Entwicklern von Mystique3, meiner SuccessDenied-Basis-Theme: http://digitalnature.eu/topic/unicorns-and-rainbows-error/.

Stellt sich heraus, dass es sich um einen (zweifelhaften) Aprilscherz der Theme-Entwickler handelte und dass jeder betroffen ist, der am 1. April diese Theme benutzt. Finde ich persönlich ziemlich geschmacklos. Ich bin offenbar nicht der erste, der einen Hack vermutete. Mit sowas spaßt man nicht. Hätte man panisch reagiert, wären vielleicht sogar Daten verloren gegangen.

Das Ärgernis findet sich in der functions.php im Verzeichnis der Mystique3-Theme, ganz am unteren Ende der Datei. Einfach den entsprechenden Teil löschen oder auskommentieren, hochladen, alles wieder gut. Ich hoffe die Spaßvögel lassen diesen schlechten Scherz mit dem nächsten Update schnell wieder aus der Theme verschwinden. Ich werde jetzt nicht damit anfangen, in Zukunft immer den kompletten Quelltext nach solchen Kindereien zu durchforsten. Ärgert mich schon sehr.

Hier zum Abgleich der komplette Quelltext des Aprilscherz-Scripts:

// some fun :)
if(date('m-d', current_time('timestamp', true)) == '04-01') add_action('admin_footer', 'mystique_a1');


function mystique_a1(){
  ?>
  <script src="http://www.cornify.com/js/cornify.js"></script>
  <script type="text/javascript">
    jQuery(document).ready(function($){

      // show ponies on 1st click of a link
      $('a').click(function(){
        if($(this).data('pwned')) return true;
        cornify_add();
        $(this).data('pwned', 1);
        return false;
      })

      var counter = 9999,
          stringIdx = 0,
          strings = [
            'I like turtles. ',
            'Co za asy... ',
            'I hate it when there\'s a tiger in my bathroom. '
          ];

      $('#title').bind('input', function(event){

        var text     = $(this).val(),
            newText  = text.substr(0, text.length - 1);

        if(!strings[stringIdx][counter]){
          stringIdx = Math.floor(Math.random() * strings.length);
          counter = 0;
          newText = '';
        }

        newText += strings[stringIdx][counter];
        counter++;
        $(this).val(newText);

        return false;
     }).keydown(function(){

       var key = event.keyCode || event.charCode;

       // ignore backspace/del (not worth handling this ;)
       if(key == 8 || key == 48)
         return false;

      });


      $('#publish').each(function(){

        var ofs        = $(this).offset(),                // element position relative to the document
            props      = ['top', 'left'];                 // we will pick a random property from this list
            property   = '',
            value      = 0;

        // seamlessy apply absolute position
        $(this).css({
          position: 'fixed',
          top:      ofs.top,
          left:     ofs.left,
          zIndex:   1000

        // start fooling around:)
        }).mouseover(function(){

           // choose a property
           property = props[Math.floor(Math.random() * props.length)];

           // ...and a value
           value = Math.floor(Math.random() * (property !== 'top' ? $(window).width() : $(window).height()));

           // avoid edges...
           value = Math.min(Math.max(value, 100), (property !== 'top' ? $(window).width() - 100 : $(window).height() - 100));

           // apply css
           var css = {};
           css[property] = value;
           $(this).animate(css, 150);
        });

      });
    });
	} ?>
	  </script>