push client als Trojaner

Obwohl der Client bei der Registrierung angab, alle Push Nachrichten dem Anwender anzuzeigen, braucht er das gar nicht zu machen! Es gibt, zumindest beim Chrome Browser, keine Instanz, die die Einhaltung dieses Versprechens prüft. Das liest sich harmlos. Was soll passieren, wenn der service worker eine Nachricht unterschlägt?

Ich baute das einfache Beispiel unter https://www.gawehns.de/pwa aus. Nun kann ich per Push Nachrichten Befehle senden.

Der einfache Trojaner …

Wie schon im vorigen Artikel beschrieben verwenden Sie den Push Companion von den Google Labs zum Senden der Nachrichten. Zunächst gilt es den dortigen public key zu kopieren und damit den Push Service einzurichten. Danach schicken Sie über den Push Companion eine Nachricht. Diese nimmt der Browser entgegen und gibt sie an den service worker weiter. Normalerweise sollte dieser die Nachricht in einer Notification anzeigen.

Zwei Befehle habe ich eingebaut:

  1. Wenn eine Nachricht mit “pst” anfängt, merkt sich der service worker den Inhalt der Nachricht in einer Variable und zeigt sie nicht an. Bei der nächsten Nachricht ohne “pst” hängt er die letzte “pst” Nachricht vorne an. Ein service worker kann also Daten zwischen den Nachrichten speichern!
  2. Bei “get” nimmt der service worker an, dass eine URL folgt. Hier verwendet er den fetch Mechanismus zum Laden der URL. Falls dies gelingt, zeigt er das über eine Nachricht an. Dabei verwendet er den Promise Mechanismus.

Mit den beiden Mechanismen hat ein böser Programmierer interessante Möglichkeiten. So kann er:

  • Per get (127.0.0.1 — 255/) alle im lokalen Netz angeschlossene Geräte prüfen, ob ein nicht ganz so sicheres Teil dabei ist. Im Erfolgsfall wird der Angriff nachgeladen und ausgeführt. Dann wäre der Router/Drucker/Webcam offen für alles.
  • Bitcoins berechnen. Immer mal wieder ein paar Rechenaufgaben herunterladen, berechnen und Ergebnisse zurückmelden. Bei genügend Clients hat man einen virtuellen Supercomputer.
  • Sich für eine verteilte Denial of Service Attacke bereit machen.

… kann nicht beobachtet werden

Wenn Sie in den Developer Tools die Arbeit von gawehns.de/pwa beobachten, können Sie die Meldungen in der Console sehen und mitverfolgen.  Ein Anwender hätte in diesem Fall noch eine gewisse Kontrolle, was ein service worker mit den push Nachrichten veranstaltet. Anders sieht das aus, wenn die Webseite noch gar nicht offen ist. Dann läuft der service worker in einem Kontext, der nicht offensichtlich ist.

Das können Sie überprüfen, in dem Sie den Push Companion in einem anderen Browser ausführen. Ich habe mir dazu neben dem Chrome noch den Firefox installiert. So konnte ich den Chrome beenden und über den Firefox die Nachrichten schicken. Die “pst” und “get” Befehle kamen, wie erwartet an, sobald ich den Chrome startete. Aber die Console unter gawehns.de/pwa zeigte keine Meldung an. Die Logdaten waren nicht in der Datenbank!

Wenn eine Webseite nur gelegentlich den Benutzer über einen neuen Artikel benachrichtigt und sonst in aller Regel still ist, würde ein böses Verhalten gar nicht auffallen. Habe ich so etwas auf meinem Browser?

Die Service Worker auf meinem Browser

Die Development Tools von Chrome zeigten diesmal noch mehr service worker an. Seltsame Implementierung sah ich:

  • https://jessica-ebert.pushcrew.com/background-worker.js:
    Hier wird richtig kommentiert, was nicht gemacht werden soll. Trackingcodes werden gesetzt und bei der Implementierung des push Evenhandlers findet sich:

              // Payload data is not present get data from our server and process it. It will be obsilite soon.
              return fetch(_wingifyPush.trackingUrl + '/getMessage.php?hash=' + _wingifyPush.hash + 
                        '&subscriptionId=' + subscriptionId).then(function (response) {

    Das ist genau das, was ich dort nicht haben will. Wenn die Webseite nicht offen ist, sollte bestenfalls eine kleine Meldung kommen und dann kann ich sagen, ob ich mehr lesen will oder eben nicht.

  • https://monk.webengage.com/service-worker.js?_=277:
    lädt nach:

    importScripts('https://ssl.widgets.webengage.com/js/service-worker.js');

    Das geladene Skript ist minifiziert und liest sich so:

    var webengage=self.webengage||{};!function(e,t,n){!function(e,n){t.__loaded||(t.__loaded=!0,t.require=function(r){if(!e[r]){if(!n[r])throw new Error(‘Cannot find module “‘+r+'”‘);var i=e[r]={exports:{}};n[r][0].call(i.exports,function(e){return t.require(n[r][1][e]||e)},i,i.exports)}return e[r].exports},t.modules=function(r,i,o){for(var c in r)r.hasOwnProperty(c)&&!n.hasOwnProperty(c)&&(n[c]=r[c]);for(var a=0;a<o.length;a++)e.hasOwnProperty(o[a])||t.require(o[a])})}({},{}),t.modules({“webengage/util/bare”:[function(e,r,i){“use strict”;var o={copy:function(e,t,r,i){r=r!==!1;for(var o in t)if(t.hasOwnProperty(o)&&(e[o]===n||r))

Also ich entzog dann mal die Erlaubnis Push Nachrichten anzuzeigen und löschte die zugehörigen service worker.

Was nun?

Ich mag die Möglichkeit Lesern anonym Nachrichten schicken zu können. Da brauche ich keine personenbezogenen Daten zu speichern. Eine Pushsubscription vermerkt weder IP-Adresse noch Wohnort noch Browsertyp. DSGVO freut sich.

Den service worker und auch die Serverseite muss ich wohl selber programmieren. Einen kostenlosen Service wie die oben erwähnten möchte ich nicht einsezten. Meine Sachen wären kommentiert und klein. Jeder sollte sehen, was er hat.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert