Über Noël Bossart

Ich bin Senior Frontend Engineer mit einem Hang zu gutem Design – dies beinhaltet auch schöner Code. Als TYPO3 Experte bei Namics bin ich in den meisten aktuellen TYPO3 Projekten irgendwie involviert und freue mich, wenn ich mein KnowHow weitergeben kann.

A Study in … Viagra

Sherlock Holmes zum Zweiten. Der Blogpost von Jürg über gehackte TYPO3-Seiten hat viel Staub aufgewirbelt worauf mehrere SOS-Rufe von betroffenen Seitenbetreibern bei uns eingetroffen sind. Das Problem war, dass einige ältere TYPO3 Betreiber plötzlich unwissentlich potenz-steigernde Pharmazeutika verkauften. Seit wir auf dieses Problem aufmerksam geworden sind, stossen wir regelmässig auf neue Opfer des „Pharmahacks“. TYPO3 ist dabei übrigens bei weitem nicht das einzige geplagte System. Perfiderweise ist der Hack auf den ersten Blick nicht sichtbar – er wird nur wirksam, wenn der Surfer via Google auf die Seite stösst. Dann wird server-seitig neuer Text in die Webseite gerendert und beim Klick auf den Link von Google aus, gelangt der Kunde nicht auf die eigentliche Seite, sondern wird auf eine (meist russische) Seite weitergeleitet. Die verkauft Viagra – oder etwas anderes blaues.
Neulich erhielten ich erneut den Auftrag, den Verkauf blauer Pillen auf der Seite eines Dritten zu unterbinden. Diesmal wurde das Problem mit „Medikamentenhack“ beschrieben.

Hier folgt ein Bericht meiner Spurensuche in der Hoffnung, dass Anderen mit den selben „Krankheitssymptomen“ geholfen werden kann.
Als erstes habe ich mich auf dem System, im TYPO3 Backend und auf dem Server etwas umgesehen. Dabei handelte es sich nicht um eine „verwahrloste“ Webseite sondern um eine recht gut ausgebaute Plattform mit einem relativ aktuellen TYPO3 Core und einem sauberen Aufbau und umfangreicher Funktionalität. Ein eher grosser Auftritt.

Gefährliche Extensions

Auf Anhieb sind mir jedoch einige potenziell (sehr) gefährliche Extensions aufgefallen, die auf einem Live-System nichts verloren haben: „t3quixplorer“ – erlaubt die Navigation auf dem Filesystem mehr oder weniger uneingeschränkt und ermöglicht das Bearbeiten von PHP-Scripts direkt über das Webinterface – der reinste Security-Alptraum. Es ist nicht auszuschliessen, dass diese Extension von einem der Angreifer installiert wurde. „devlog“ ist eine Extension welche zu Entwicklungszeiten nützlich sein kann – jedoch nicht in einem Live-System. Ein anderer Kandidat, welcher jedoch nicht installiert war, ist die „phpmyadmin“ Extension, welche oft aus Bequemlichkeit installiert wird. Auch diese Extension stellt ein beträchtliches Sicherheitsrisiko dar. Im übrigen beinhaltete das System einige „handgemachte“ Extensions – schnell zu erkennen an fehlenden Icons und der aussagekräftigen Versionsnummer 0.0.0 – Stable? Ja genau!

Backend-User

Ich habe ausserdem alle Backend-User überprüft und mit dem Kunden zusammen sichergestellt, dass keine unbekannten Nutzer registriert waren. Sollte dies der Fall sein, würde ich empfehlen, alle User neu anzulegen und neue, sichere Passwörter zu vergeben.

Spurensuche im Dateisystem

Danach habe ich mich etwas vertieft auf die Spurensuche gemacht. Aus Erfahrung weiss ich mittlerweile, wonach ich suchen muss. Eine Suche im Filesystem nach „base64_decode(“ führt meist zu verdächtigen Code-Zeilen oder Dateien:

find . -name "*.php" -print | xargs grep "eval(base64_decode("

Meist sind infizierte Dateien im Ordner typo3conf/ zu finden. Darin befinden sich die von TYPO3 auszuführenden Extensions. Der Code darin kann potenziell schädlich sein.
Auf diese Weise bin ich auf zwei verdächtige Dateien gestossen. Eine Datei war in einer nicht öffentlichen, für Kundenbedürfnisse entwickelten Extension enthalten. Die andere im ./uploads/ Ordner der bekannten Newsletter-Extension tx_directmail.

./uploads/tx_directmail/trololo.php:<?php eval(base64_decode("ZXZhbChiYXNlNjRfZGVjb2RlKCJaWFpoYkNoaV
lYTmxOalJmWkdWamIyUmxLQ0phV0Zwb1lrTm9hVmxZVG14T2FsSm1Xa2RX
YW1JeVVteExRMHBoVjBad2IxbHJUbTloVm14WlZHMTRUMkZzU20x…

In beiden Fällen war es dem Angreifer möglich, über ein ungenügend geschütztes Formular PHP-Dateien auf das System zu laden. Geschieht dies, und sind diese Dateien auch ausführbar, hat man verloren.
Bei genauerem Hinsehen habe ich in der handgestrickten Extension gleich noch mehr zerstörerische Dateien gefunden welche die unscheinbaren Namen „class.php“ und „footer.php“ trugen. Ich musste erst beim Dienstleister des Kunden nachfragen, um sicher zu stellen, dass es sich wirklich um bösartige Dateien handelte. In diesen Fällen hatten die Angreifer ganze Arbeit geleistet – auch das Erstelldatum war ein weit zurückliegendes. Oft kann man im System auch einfach nach Files suchen, die im Zeitraum des Hacks verändert wurden. Ich konnte diesen durch verdächtige Files auf etwa 76 Tage zurückliegend vermuten und bin mit dem Befehl

find . -iname "*.cache" -mtime -77 -mtime +75 -type f

auf weitere verdächtige Dateien gestossen. Da im Ordner typo3conf während dem Betrieb eigentlich keine Dateien geändert werden sollten, sind dies zumindest dort, nur eine Hand voll. Mein Tipp: in typo3conf/ext/ darf auf einem Live-System gar nichts geändert werden können. Dem Server (Apache) sollen also alle Schreibrechte auf typo3conf/ext/ entzogen werden. Auch localconf.php darf nie verändert werden – damit wird es für einen Angreifer sehr schwer, nachträglich Extensions zu installieren, ohne dass er Serverzugriff hat.

Bereits erwähnte class.php war mehrfach base64 encoded und nachdem ich diese mehrfach decodiert hatte wurde ihr Zweck offensichtlich. Sie leitet die Benutzer welche von viagra-verseuchten Google-Resultaten kommen auf die russischen Verkaufsseiten weiter:

Ja ist denn heut‘ schon Weihnachten?

Bei der Analyse von ./uploads/tx_directmail/trololo.php wurde ich leicht überrascht. Ebenfalls nach mehrmaligem encoden kam folgendes zum Vorschein:


Ein ausgewachsenes Backdoor! Inklusive Passwortschutz. Klar russischen Ursprungs. Mit diesem Tool kann man auf einem Server so ziemlich alles machen. Dateien erstellen, löschen, bearbeiten, Rechte setzen. Damit kann man die localconf.php auslesen – dort steht (meist) der MySQL User und das Passwort im Klartext. Somit kann der Angreifer auch auf die Datenbank zugreifen. Doppelt dumm, wenn der gleiche User auf mehrere Datenbanken Zugriff hat. Wenn man localconf.php nicht schreibgeschützt hat, kann er ausserdem ein neues Install-Tool Passwort erstellen. Damit kann er sich dann einen Backend-Administrator erstellen – etwas einfacher als direkt über die DB. Netterweise nennt TYPO3 bei einer missglückten Anmeldung am Install-Tool auch gleich den dazu benötigten MD5 Hash den man dann nur noch im localconf.php eintragen braucht.
Das Backdoor in Action:

Und weiter geht’s…

Nachdem ich die Suche bereits abbrechen wollte – es war mittlerweile schon spät – bin ich im fileadmin/ in den Templates der Webseite auf eine weitere mysteriöse Datei gestossen – eine PHP Datei unter den CSS Files; en.php
Diese enthielt neben den verdächtigen base64 Codes auch noch folgenden aufschlussreichen Text:

Codz by angel(4ngel)
Make in China
Web: http://www.4ngel.net

Die Chinesen waren also auch am Werk! Nach erneut mehrmaligem Encodieren und Entfernen eines Passwortschutzes wurde offensichtlich, dass die Chinesen den Russen mittlerweile – zumindest im Design – voraus sind. Ebenfalls eine mächtige Hintertüre – einmal in schön.

Fazit, Suche, Massnahmen

Abschliessend konnten wir den Grossteil des Hacks wohl innerhalb einiger Stunden finden und entfernen. Nach dem der übliche Selbstheilungsprozess von Google eingesetzt hatte sind nun die Suchresultate wieder frei von Viagra. Für die Suche nach infizierten Files benutzen wir die Dateisystemsuche nach den Begriffen eval() und base64_decode(), Datumsangaben, verdächtige PHP-Dateien an unüblichen Orten – PHP-Files im uploads Ordner oder in andern Ordnern mit normalerweise statischen Inhalten. Auch eine Hilfe für das schnelle Finden von Schadcode kann sein, wenn die TYPO3 Temp-Files im typo3conf/ Ordner nach base64_decode durchsucht werden. Diese Dateien werden von Typo3 geladen und enthalten einen Zusammenzug vieler ausgeführter Dateien. Oft sieht man dort schnell, ob, und wo ungefähr, ein System vom „Pharmahack“ befallen ist. Handgemachte Extensions die nie den Weg ins TYPO3 Repository gefunden haben sind ein erhöhtes Sicherheitsrisiko. Alle Formulare mit Upload-Funktionalität sind ein möglicher Angriffspunkt. Auch in die Datenbank sollte man einen Blick werfen. Es kann sein, dass in den Tabellen von RealURL unerwünschte Weiterleitung enthalten sind. Auch in tt_content oder in der pages Tabelle kann nach Viagra gesucht werden. Ausserdem sollte man alle Cache-Tabellen leeren.

Die befallenen Dateien und Extensions werden gesäubert oder entfernt. Nicht (mehr) benötigte Extensions sollten vom System gelöscht werden – nicht nur deaktiviert! Unnötige Backend- und Frontend-User sollten ebenfalls gelöscht und die Passwörter sicherheitshalber angepasst werden.
Alle Schreibrechte für den Server sollten auf typo3conf/ext und auf der localconf.php entfernt werden. Dies gilt selbstverständlich auch für den ganzen TYPO3-Core. Sicherheitshinweise von TYPO3 sollten ernst genommen werden:

Das Install-Tool kann auf dem Live-System entfernt werden und der Zugriff auf das Backend nur für einen bestimmten IP-Range, vielleicht über eine spezielle Sub-Domain und zusätzlich mit einem .htaccess Schutz, versehen werden. Auch HTTPS für das Backend schadet kaum.
Natürlich sollte darauf geachtet werden, dass TYPO3 und verwendete Extensions auf einem aktuellen Stand sind. TYPO3 Bug-Fix Releases sollten wenn möglich immer installiert werden da diese Security-Fixes enthalten und normalerweise problemlos zu installieren sind.

Flexible & erweiterbare jQuery Plugins

jQuery ist ein mächtiges Framework welches das Arbeiten mit JavaScript stark erleichtert. Mittlerweile ist jQuery mit Abstand das verbreitetste JavaScript Framework der Welt. Ganze UI-Elemente wie Tabs, oder Funktionsblöcke wie etwa eine Bildergalerie sucht man jedoch – bei jQuery selber – vergeblich. jQuery stellt lediglich zahlreiche mehr oder minder kleine Helfer zur Verfügung, welche es ermöglichen, solche Dinge mit geringem Aufwand zu erstellen.

Nun ist es natürlich nicht praktisch komplexe Funktionen wieder und wieder – und für jedes Projekt neu – zu schreiben. Hier kommen die „jQuery Plugins“ ins Spiel. Ein jQuery Plugin ist in der Regel eine Erweiterung von jQuery und kann beliebig komplexe Funktionen – von History Handling über UI-Elemente bis zu Lightboxen – bereitstellen.

Aufbau eines Plugins

Die jQuery Plugin API dient dazu, jQuery um neue Funktionen zu erweitern:

// jQuery um Tab Funktion erweitern:
$.fn.tabsPlugin = function(userOptions) {
   // Plugin Code...
}

Plugins sind meist sehr ähnlich aufgebaut. Sie werden in der Regel auf ein Set von HTML Elementen angewendet und man kann das Verhalten des Plugins mit Optionen etwas beeinflussen. In etwa so:

var options = {
     activeTab: 2
};
$('div.tabs').tabsPlugin(options);

Damit würde man etwas HTML Code…
2307-html Code.png

…in ein Modul verwandeln das etwa wie folgt aussieht:
2306-Tabs-thumb-500x83-2305.png

Das Plugin hat dabei meist eigene Optionen, sogenannte Defaults. Diese werden durch die Optionen, welche der Benutzer dem Plugin beim Aufruf mitgegeben hat ergänzt:

var options = $.extend({}, $.fn.tabsPlugin.defaults, userOptions);

Innerhalb des Plugins, wird danach die entsprechende Plugin-Funktion auf jedem einzelnen der übergebenen Elemente ausgeführt. Dabei muss darauf geachtet werden, dass die Funktion nur auf das jeweilige Element Einfluss hat, damit mehrere Elemente auf der Seite die gleiche Funktionalität haben können.

var $tabSets = $(this);
$tabSets.each(function(){
     // Auf jedem Element die gewünschte Funktion ausführen
     var $tabSet = $(this); // Aktuelles Tab-Set
     ...
});

Nun soll’s ein bisschen anders sein…

Ein Problem vieler Plugins ist, dass sie zwar meist ihre Aufgabe gut erledigen, nicht selten auch viele Optionen mitbringen, aber nicht flexibel oder erweiterbar sind. Nehmen wir ein Plugin, das aus einem Set an HTML Elementen ein Tab-UI generieren soll. Dieses Plugin übernimmt das Sammeln der Tabs und zugehörigen Panels, sowie das Ein- und Ausblenden der Panels beim Klick auf ein Tab. Ausserdem bringt es noch einige Optionen mit, womit der Benutzer festlegen kann, welche Klassen die ausgewählten Tabs haben sollen und welches Tab zu Beginn aktiviert werden soll. Ist doch Perfekt, nicht?

Was nun, wenn der Inhalt des Panels beim Aufruf der Seite noch nicht vorhanden ist sondern erst nachgeladen werden soll, wenn man das entsprechende Tab aktiviert? Herkömmliche Plugins versagen hier oft und gewünschte Funktionalität muss direkt im Plugin eingefügt werden. Dabei geht die Update-Fähigkeit verloren und es leidet die Wiederverwendbarkeit und Sicherheit des Projekts. Im Wissen, dass der Benutzer vielleicht mit dem Plugin noch weiter Anwendungsfälle hat neigt der Autor des Plugins dazu, möglichst viele Funktionen in sein Plugin zu stecken, da er es ja flexibel halten möchte. Damit wird es gross, schwerfällig und unübersichtlich und verfügt über eine Menge Funktionen, welche viele unter Umständen gar nicht brauchen. Der Autor des besagten Tab-Plugins muss dabei an Tastatur-Bedienbarkeit, Ajax- und History-Fähigkeit sowie vieles mehr denken.

Evented jQuery Plugins = flexibel & erweiterbar

Eine Lösung für dieses Problem lautet Custom Events oder kürzer – Evented. Dabei muss sich der Plugin Autor überlegen, welche grundlegende Funktionen das Plugin benötigt und stellt diese in einer möglichst schlichten Form zur Verfügung.

Ein Tab-UI-Element hat im Grossen und Ganzen eine Funktion: Beim Klick auf ein Tab, soll das zugehörige Panel aktiviert und alle anderen deaktiviert werden. Wir brauchen also eine „activate“ Funktion. Ausserdem müssen zu Beginn alle Tabs gesucht, und die zugehörigen Panels gespeichert werden. Dazu benötigen wir eine „setupTabs“ Funktion. Des weiteren sollten die Panels wissen, zu welchem Tab sie gehören: „setupPanels„. Beim Aufruf der Seite sollen diese beiden Funktionen ausgeführt werden und das erste Tab aktiviert werden, dazu brauchen wir noch eine letzte Funktion, die „initialize“ Funktion.

Diese Funktionen sind „Events“. Jedes übergebene Set an HTML Elementen wird mit diesen Events versehen. Da der Event damit immer zu einem Tab-Element gehört, kann damit auch das Problem von allfälligen Konflikten mit anderen Tab-Elementen einfach gelöst werden. Wenn auf einer Seite zwei Tab-Elemente vorhanden sind, beeinfluss Tab-Verbund eins den zweiten Tab-Verbund nicht, wenn darauf der activate Event ausgeführt wird:

...
$tabSets.bind("activate",
        function(e, selected) {
            // selektiertes Tab aktivieren
        }
);
...

Events nach Aussen verfügbar machen

Der Trick besteht nun darin, dass diese Funktionen nicht einfach fest in das Plugin integriert sind, sondern das jede einzelne Funktion in ein Array gepackt wird, welches über ein Objekt customEvents von aussen Zugänglich ist. Die Funktions-Array können dadurch ergänzt, oder gar ganz überschrieben werden, bevor das Plugin auf ein Set von HTML Elementen angewendet wird.

var customEvents = {
    initialize: [function(options) {
        this.bind("initialize." + options.namespace,
        function(e) {
            // Tabs und Panels vorbereiten
            //und erstes Tab Aktivieren
        });
    }],

    setupPanels: [function(options) {
        this.bind("setupPanels." + options.namespace,
        function(e) {
            // Panels mit zugehörigem Tab verbinden
        });
    }],

    setupTabs: [function(options) {
        this.bind("setupTabs." + options.namespace,
        function(e) {
            // Tabs suchen und activate Funktion bei klick ausführen
        });
    }],

    activate: [function(options) {
        this.bind("activate." + options.namespace,
        function(e, selected) {
            // Alle Tabs deaktivieren und selektiertes
            // Tab und Panel aktivieren
        });
    }]
};

Events ergänzen

Im unserem Beispiel wollten wir, dass der Inhalt des Panels erst vom Server geladen wird, wenn das Tab aktiviert wird. Die Vorgehensweise ist nun denkbar einfach, man fügt einfach vor der Plugin-Standard-Funktion eine neue Funktion hinzu, welche den Inhalt des Panels via Ajax vom Server lädt. Dabei muss man zu keiner Zeit das Plugin selber verändern. Wenn der Plugin Autor ein Bug-Fix veröffentlich, kann das Plugin einfach aktualisiert werden – die Grundfunktionen werden die gleichen bleiben und die Erweiterung wird nicht tangiert da sie sich ausserhalb des Plugins befindet.

// Neue Funktion vor die bestehende
// activate Funktion schieben:
customEvents.activate.unshift( function(options) {
    // Die Erweiterung auf das Grund-Element
    // (nicht die einzelnen Tabs) binden:
    this.bind("activate." + options.namespace,
        function(e, selectedTab) {
            // Den Inhalt des Tabs hier
            // per Ajax in das Panel laden:
            var url= selectedTab.href;
            $(selected).data('$panel').load(url);
   });
});

Der Kern des Plugins ist dabei lediglich dafür verantwortlich, dass die Default Einstellungen mit den Benutzer-Optionen ergänzt werden und dass danach alle Tab-Elemente die Custom Events erhalten.

Hello World!

Nachdem man dieses erweiterbare und flexible Tabs-Plugin geschrieben hat, ist es natürlich schön, wenn sich der Rest der Welt auch daran erfreuen kann. In meinem nächsten Post werde ich zeigen, wo und wie man ein eigenes Plugin veröffentlichen kann und was dabei zu beachten ist.

Die vielleicht grösste JavaScript-Konferenz der Welt

1513-bayjqcon-thumb-500x178-1512.png
Die Apfellogodichte auf dem Microsoft-Areal in Mountain View war vergangenes Wochenende überdurchschnittlich hoch. Grund dafür war die „wohl grösste JavaScript Konferenz der Welt„. An der Bay Area jQuery Konferenz 2010 war alles versammelt was Rang und Namen in der JavaScript- und insbesondere in der jQuery-Welt hat.

John Resig, der Schöpfer und geistige Vater von jQuery, eröffnete die Konferenz mit ihren fast 500 Teilnehmern und danach folgen etwa dreissig Sessions – Schlag auf Schlag – randvoll mit Informationen. Johns Ansprache wurde per Livestream in den zweiten Raum übertragen – nicht alle Personen passen in den mit allen technischen Finessen ausgestatteten Raum Eins des Microsoft Conference Centers.

1502-jqcon (7 of 7)-thumb-500x323-1501.jpg

Verteilt in den zwei Räumen finden jeweils parallel 45-minütige Sessions statt. „High Performance jQuery“, durch Steve Souders, Nicholas C. Zakas und einem herausragend Robert Duffy und in drei Sessions vertreten – eines der thematischen Schwerpunkte der Konferenz.

«0.1 second is about the limit for having the user feel that the system is reacting instantaneously»

1505-Nicholas C. Zakas-thumb-500x229-1504.jpg
Nicholas, kein ausgesprochener jQuery-Experte, dafür aber bewaffnet mit jahrelanger Erfahrung als JavaScript Entwickler – und als Principal Frontend Engineer der Yahoo!-Homepage eine Koryphäe auf dem Gebiet – vermittelte auf äusserst eingängige Art und Weise, warum die Ausführung von JavaScript den Browser-UI Thread blockieren, und dadurch eine Webseite träge erscheinen lassen kann – und präsentierte gleich auch Lösungen, um dies zu verhindern. Des Weiteren erläuterte er auch die Problematik, welche durch die besonders CPU-lastige Neuberechnung – ein so genannter Reflow – der Seite durch JavaScript-Manipulationen entsteht und wie man solche Reflows vermeiden oder zumindest reduzieren kann.

Use the right tools for the right job

Weniger Neues – dafür aber zum Brüllen komisch – vermittelte der Brite Robert Duffy anschaulich, wie man mit wenigen Tricks die Performance von jQuery-Applikationen um ein Viellfaches verbessern kann. Durch ein witziges Beispiel seines britischen Rennwagens auf einer jQuery-gesponsorten Rennbahn vermittelte er die Prinzipien von Selektor-Caching und wie man durch richtigen Einsatz der verfügbaren Mittel – zum Beispiel durch die Verwendung von CSS-Klassen statt der show(); und hide(); Funktionen – die Performancegewinne erzielen kann. Quintessenz:

«Performance is no Rocket Science but has a massive Impact if you pay attention to the small things.»

Und die Aussage des Tages:

«Use Tables…»

Werbung ist (oft) nicht nur langweilig, sie beeinträchtigt (meist) auch die Performance der Webseite

1507-jqcon (3 of 7)-thumb-500x289-1506.jpg
Das war eine der Grundaussagen von Steve Souders, welcher in seinem schon oft gehaltenen Vortrag einige neue und sehr praktische Tools vorgestellt hatte. Darunter ein wohl oft übersehenes Tab „Tools“ in YSlow welches einige praktische Werkzeuge enthält – All JS Beautified, wenn man mal wieder das komprimierte Apple-JavaScipt entschlüsseln will – und eine Webseite, mit der man die Performance einer Seite in IE7 und IE8 in ausführlich testen kann. Besonders spannend daran ist die Möglichkeit, den Aufbau der Seite über Zeit in Screenshots und als Video aufzuzeichnen. Ein praktisches Tool um dem Kunden eine Performance-Verbesserung schmackhaft zu machen.

How To Manage Large Applications with jQuery

Alex Sexton präsentierte – in seinem ihm eigenen Humor – gleich drei Methoden um grosse jQuery Applikationen handbar zu machen:

  1. Nativ / Pseudo-Classical
  2. Classical
  3. Prototype Inheritance (fits into the language the best)

zusammen mit seiner Präsentation bestimmt ein (vertiefter) Blick wert.

«OO Code in JavaScript is Crippled Evented Code»

Ebenfallst eine Perle unter den Vorträgen war { Evented von Yehuda Katz. Mit seiner polarisierenden Aussage

«Don’t use OO to organize your code – There are better concepts.»

regte er viele Diskussionen an und lieferte gleich einige schlagkräftige Argumente um seine Aussage zu untermauern. Leider sind seine Slides und Beispiel noch nicht online… Einen Blogpost in dem dieses Prinzip erklärt wird hat findet sich hier. Nebenbei erwähnte Yehuda noch haml, sass and compas – drei Dinge die wohl ebenfalls erwähnt und beachtet werden dürfen.

«Design is not just what it looks like and feels like. Design is how it works.» Steve Jobs

Neben vielen sehr technischen Vorträgen gab es auch (vereinzelte) Ausnahmen. Die einzige Folie mit Code in der Präsentation des redegewandten Steve Smith:

jQuery.fx.speeds._default = 
   ( 
      jQuery.browser.ie && 
      jQuery.browser.version < parseInt(8,10)
   ) ? 0 : 200;

Steve erläuterte warum Entwickler Interaction-Design ernstnehmen sollten - und lieferte ein paar Tipps, wie man ein UI entwickeln kann, welches dem Benutzer Zuversicht schenkt, statt Misstrauen bei der Bedienung zu wecken. Zusammengefasst:

  1. Design the User Experience first
  2. Interactions are meant to
    impress the user
    impress the client
    
engage and enhance
  3. Speed is important - distractions are bad
  4. It's our job to build user confidence
  5. Don't solve problems with code - Solve the problem, then write the code

jQuery als Browser-Standard?

1511-20100426-01-38-47-IMG_9786-thumb-500x255-1510.jpg

Zum Schluss hielt John Resig eine Rede zur Lage der Nation von jQuery in der er über geplante Features wie Script Loading und einigen offiziellen Plugins (Template- und Data Binding Plugin) Stellung nahm. Das jQuery Team und insbesondere John ist ausserdem in Gesprächen mit unterschiedlichen Browser-Herstellern um Teile von jQuery zu einem Browser-Standard zu machen:

«I've been talking width Mozilla, IE, Crockford, and the W3C to come up with a good result that everyone is happy with and that is shipped with Browsers»

1509-4465177194_eee5cbd9fa_o-thumb-500x181-1508.png
Auf
seinem triumphalen Siegeszug durch das Internet hat jQuery mittlerweile auf zwei von drei Webseiten Einzug gehalten und eine Kehrtwende ist nicht in Sicht. Diese Konferenz - mit Entwicklern aus aller Welt und aus Firmen wie google, Yahoo! und Microsoft - hat dies eindrücklich gezeigt. Die nächste jQuery Konferenz in London steht bereits vor der Türe und ich für meinen Teil kann eine Teilnahme nur empfehlen. Das geballte Know-How und die informativen und sogleich humorvollen Präsentationen sowie viele Gespräche - sowohl vor als auch nach den Sessions - das gemütliche After-Party-Bier bei angeregter Unterhaltung, die Chance neben Jay Freeman - a.k.a. Saurik, dem Entwickler des inoffiziellen iPhone-App-Stores - zu sitzen machen diese Konferenz zu einem must see.

Zum Nachschlagen

Alle Die meisten Slideshows kann man unter Speakerrate betracht. Es lohnt sich.