Getarntes JavaScript - Finger weg von meinem Code!

JavaScript-Obfuscator: Schutz für den eigenen Code
Keine Kommentare

Sie wollen Ihren JavaScript-Code mit den wertvollen Algorithmen vor Angreifern schützen? Im Bereich der Obfuscation gibt es einige Werkzeuge – von einigen Minimierungswerkzeugen bis hin zu kompletten serverbasierten Lösungen – die dem Angreifer das Leben erschweren. Oft reicht es völlig aus, wenn der Angreifer nach einem kurzen Blick beschließt, dass er lieber eine andere Applikation klont.

Das Feld der Obfuscation von JavaScript ist weit: Es reicht von einfachen Minimierungswerkzeugen bis zu kompletten serverbasierten Lösungen. In diesem Artikel möchte ich Ihnen einige Möglichkeiten konzeptuell vorstellen, um mehr über die verschiedenen Vorgehensweisen zu erfahren. Schon an dieser Stelle sei angemerkt, dass Obfuscators keinen Ersatz für eine serverseitige Verifikation darstellen. Ein als Fuzzing bezeichnetes Verfahren erlaubt Angriffe gegen extrem komplizierte Protokolle – der Ratschlag, vom Client eingehende Informationen als toxisch zu betrachten, gilt auch bei Verwendung aller in diesem Artikel besprochenen Methoden.

Mit Brachialgewalt!

Wie so oft in der Welt der Informatik gilt auch hier, dass es keine universell sichere Lösung gibt. Die Aufgabe aller besprochenen Verfahren ist, einen Angriff so teuer zu machen, dass er sich für Hacker nicht lohnt. Hat man es mit extrem empfindlichem oder fragwürdigem geistigen Eigentum zu tun, so ist die Nutzung von Obfuscators oft nicht ausreichend. In diesem Fall empfiehlt es sich, auf eine Client-Server-Architektur zu setzen. Ein Beispiel dazu ist in Abbildung 1 zu sehen, bei der ein fiktives Berechnungsprogramm in zwei Komponenten aufgeteilt wird.

Abb. 1: Liegt die Logik am Server, ist der Clientcode weitgehend wertlos

Abb. 1: Liegt die Logik am Server, ist der Clientcode weitgehend wertlos

Diese auf den ersten Blick seltsame Vorgehensweise ist in Zeiten von WebSocket und Co. problemlos implementierbar. Überraschenderweise beklagen sich Nutzer in der Praxis nur wenig, wenn ihr Programm ohne Netzwerkverbindung nicht funktioniert. Der Autor testete das unter Firefox OS: Trotz permanenter Verbindung zum Server erhielt der hauseigene wissenschaftliche Taschenrechner beste Bewertungen. In eine ähnliche Kerbe schlägt die Nutzung eines Produkts wie beispielsweise Emscripten. Das von Alon Zakai entwickelte Framework erlaubt die Kompilation von C-Code, der danach in einer virtuellen Maschine zur Ausführung gelangt.

Der Code befindet sich zwar auf der Maschine des Klienten, ist aber extrem schwer zu analysieren. Emscripten-Code ist von der Komplexität her mit Qt und Co. vergleichbar. Beschwerden über Disassembler-Attacken auf C++-Programme findet man, anders als in der Welt von Java oder .NET, nur sehr selten.

Eine Frage des Konzepts!

Möchten Sie nicht auf Brachialmethoden setzen, so steht eine Vielzahl von Obfuscators zur Verfügung. Sie verhalten sich im Großen und Ganzen so, wie man es aus der Java-Welt kennt. Links kommt lesbarer Code in die Blackbox, die auf der anderen Seite verfremdeten Code ausspielt. Im Idealfall ist das Chiffrat sofort ausführbar. Dass die Praxis anders aussieht, sei schon hier angemerkt.

Bei der Arbeit mit JavaScript Obfuscators ist eine Besonderheit zu beachten. Während Obfuscators für andere Programmiersprachen normalerweise durch die Reduzierung des Programmumfangs zu einer Beschleunigung des Programms beitragen, wirken sich JavaScript-Verschwurbeler oft negativ auf die Gesamtperformance aus. Die Ursache dieses paradoxen Verhaltens liegt in Zweierlei: erstens ist der verwurstete Code oft umfangreicher als die Basisvariante, was die Ausführung verlangsamt. Das ist nicht vermeidbar, da das Einführen von Arrays, globalen Sprungtabellen und ähnlichen Nettigkeiten naturgemäß Rechenleistung kostet.

Ein zweites, und noch lästigeres Antipattern, ist die Verwurstung von bei Drittanbietern bezogenen Bibliotheken. Zur Erklärung: Verwenden Sie eine häufige Version von jQuery, so kann der Browser diese aus einem CDN (oder sogar aus seinem lokalen Cache) beziehen und auf diverse Arten beschleunigen. Eine von Ihnen verschlüsselte Variante der Bibliothek müsste stattdessen komplett neu eingelesen und geparst werden, was wertvolle Zeit verschlingt.

Der von Timofey Kachalov entwickelte JavaScript Obfuscator ist ein Klassiker der Szene. Er unterscheidet sich von Konkurrenten wie UglifyJS dadurch, dass er sich nicht nur auf das Entfernen von Steuerzeichen und sonstigen Lustigkeiten beschränkt, sondern auch Eingriffe in die Codestruktur durchführt, um die Nutzung von JavaScript-Verschönerungsprogrammen zu erschweren. Auf Wunsch integriert der Obfuscator sogar Checkroutinen, die den Code bei Erkennung der Änderung des Formats automatisch deaktivieren.

Auch wenn unter https://obfuscator.io eine Onlineversion des Werkzeugs bereitsteht, empfiehlt sich für ernsthafte Versuche die Nutzung einer lokalen Installation. Hierzu ist Node.js erforderlich, auf der Workstation des Autors war Version 10.1.0 installiert. NPM ist für das Herunterladen verantwortlich und lag unter Ubuntu 14.04 in Form der extern heruntergeladenen Version 5.6.0 vor.

JavaScript Obfuscator lässt sich auf mehrere Arten installieren. Wer nicht mit einem in Node.js lebenden Projekt arbeitet, sollte das Programm im Interesse der Bequemlichkeit global installieren. Hierzu dient folgende Kommandosequenz (falls es zu Berechtigungsfehlern kommt, müssen Sie vor dem Aufruf noch sudo platzieren):

tamhan@TAMHAN14:~$ npm install -g javascript-obfuscator
. . .
+ javascript-obfuscator@0.18.1
added 103 packages in 8.074s

Prüfen Sie nach dem Durchlaufen des Kommandos die erfolgreiche Installation, indem Sie das Kommando javascript-obfuscator in Ihr Terminal eingeben. Bei richtiger Parametrisierung präsentiert sich das Ergebnis wie in Abbildung 2 gezeigt.

Abb. 2: Der JavaScript Obfuscator ist einsatzbereit

Abb. 2: Der JavaScript Obfuscator ist einsatzbereit

Zur Demonstration der Obfuskationsleistungen wollen wir im nächsten Schritt ein kleines Beispielprogramm realisieren. Sein Korpus präsentiert sich wie in Listing 1 zu sehen.

var myString = "Hallo SUS"

function doTheTrick(){
  var chiffrat;
  chiffrat = rot13(myString);
  return chiffrat;
}

function rot13(str) {
  var re = new RegExp("[a-z]", "i");
  var min = 'A'.charCodeAt(0);
  var max = 'Z'.charCodeAt(0);
  var factor = 13;
  var result = "";
  str = str.toUpperCase();
  
  for (var i=0; i<str.length; i++) {
    result += (re.test(str[i]) ?
      String.fromCharCode((str.charCodeAt(i) - min + factor) % (max-min+1) + min) : str[i]);
  }
  return result;
}

In diesem – auf den ersten Schritt primitiv aussehenden – Beispielprogramm finden sich zwei Bösartigkeiten. Erstens haben wir eine Methode namens rot13, die eine – zugegebenermaßen etwas primitive – Form der Verschlüsselung realisiert. Die von rot13 übernommene Implementierung basiert auf sprechenden Variablennamen, was einem Angreifer die Analyse wesentlich erleichtert.

Mindestens ebenso heiß ist die Verwendung der String-Konstante. Hierbei handelt es sich um einen klassischen Angriffsvektor: Eine der ersten Vorgehensweisen bei der Analyse eines ROM-Dumps ist, den Disassembler zur Suche nach Strings zu animieren.

Die praktische Erfahrung lehrt, dass JavaScript-Obfuscatoren mit in HTML vorliegendem Code ihre liebe Not haben. Aus diesem Grund binden wir die .js-Datei in einen zweiten Harnisch ein, der seinerseits ebenfalls eine Methode mitbringt (Listing 2).

<html>
<body>
  <script src="worker.js"></script>
  <script>
  function worker(){
    alert(doTheTrick());
  }
  </script>
  <button type="button" onclick="worker()">Click Me!</button>
</body>
</html>

Führen Sie das Programm sodann aus, um sich vom korrekten Aufscheinen der MessageBox zu überzeugen. Der Autor setzt hier absichtlich nicht auf komplexe DOM-Manipulationen, um den Code unseres Beispiels nicht unnötig aufzublähen.

An dieser Stelle können wir einen ersten Versuch in Richtung Obfuscation wagen:

tamhan@TAMHAN14:~/SUSObfuscate$ javascript-obfuscator . --output ./subfolder

[javascript-obfuscator-cli] Obfuscating file: worker.js...
(node:20534) ExperimentalWarning: The fs.promises API is experimental

JavaScript Obfuscator zeigt sich – siehe auch Abbildung 2 – extrem flexibel, wenn es um die Parametrierung geht. Wir übergeben momentan nur den Mindestsatz. Er weist das Produkt dazu an, im aktuellen Arbeitsverzeichnis nach JavaScript-Dateien zu suchen. Mit dem Parameter output weisen wir eine „Umleitung“ der verschlüsselten Dateien an. Würde dieser Parameter unterbleiben, fänden wir statt worker.js eine zusätzliche Kollegin mit erweitertem Namen.

Die Wahl der besten Vorgehensweise ist im Großen und Ganzen Geschmackssache. Der Autor bevorzugt die hier vorgeführte Umleitung in ein neues Verzeichnis. Eine „lauffähige“ Version der Applikation lässt sich dadurch erzeugen, dass sie die .html- und sonstigen Dateien in das Unterverzeichnis subfolder kopieren.

Wer die verschlüsselte Version des Programms ausführt, sieht, dass der rot13-veränderte String nach wie vor in einem Dialog angezeigt wird. Wesentlich interessanter ist es, den Code in der neuen Version von worker zu öffnen. Er präsentiert sich – mit Syntaxhervorhebung – wie in Abbildung 3 gezeigt.

Abb. 3: Die Übersichtlichkeit unseres Arbeiters hat sich stark reduziert

Wer den Code mit den Standardeinstellungen des Programms verschlüsselt, sieht, dass die Struktur durch Einschreibung von Methoden verkompliziert wurde. Leider sind die Schlüssel nach wie vor klar sichtbar. Neben dem Feld toUpperCase finden wir beispielsweise die Funktionen rot13 und doTheTrick, auch der Parameterstring „Hallo SUS“ wurde nur zu ‚Hallo\x20SUS‘ verändert und befindet sich prominent am Anfang der Datei.

Der String im Mittelpunkt

Die soeben durchgeführten Versuche haben die Klarheit unseres Codes stark reduziert. Leider ist es noch immer einfach möglich, die „Aufgabe“ des Programms zu erraten. Anbieter von Obfuscatoren leiden seit jeher darunter, dass sie bei der Parametrisierung mehrere Aspekte gegeneinander abwägen müssen. Neben der schwierigen Lesbarkeit gilt es, Performance und Stabilität zu beachten. Es gibt in der Praxis immer wieder Situationen, in denen ein Programm nach der Opposition nicht mehr ausführbar ist.

Für die Konfiguration der Stringverarbeitung stellt der JavaScript Obfuscator drei Parameter zur Verfügung:

--string-array <boolean>
--string-array-encoding <boolean|string> [true, false, base64, rc4]
--string-array-threshold <number>

Der erste Befehl sorgt für die Erzeugung des in Abbildung 3 gezeigten Stringarrays. Code lädt die Zeichenketten zur Laufzeit aus diesem Feld, was die Nachverfolgbarkeit der Wertebeschaffung erschwert.

Zum Verständnis des Programmverhaltens wollen wir auf http://jsnice.org zurückgreifen – einen Analysedienst, der unsauberen JavaScript-Code, wie in Abbildung 4 gezeigt, sauber zu rechnen versucht.

Abb. 4: JS NICE versucht, die Arbeit des Obfuscators rückgängig zu machen

Abb. 4: JS NICE versucht, die Arbeit des Obfuscators rückgängig zu machen

Die Methode doTheTrick() lässt sich – fast komplett – restaurieren:

function doTheTrick() {
  var match;
  match = rot13(myString);
  return match;
}

Interessanter ist die Deklaration des Wertes myString, der nun als Rückgabewert einer Funktion entsteht:

var a0_0x5c07 = function(level, ai_test) {
  level = level - 0;
  var rowsOfColumns = a0_0x1844[level];
  return rowsOfColumns;
};
var myString = a0_0x5c07("0x0");

Bemerkenswert ist hier, dass JS NICE die Variablennamen durch ein neuronales Netzwerk zu erraten versucht. Das System arbeitet mit diversen in GitHub enthaltenen Projekten, deren Informationen eingesetzt werden. Dies führt stellenweise zu lustigen Ergebnissen. Ein gutes Beispiel ist in der Methode rot13 zu finden, wo wir plötzlich eine Variable namens pixelSizeTargetMax antreffen:

function rot13(PL$120) {
  . . .
  var pixelSizeTargetMax = . . .

Damit können wir zum Stringarray zurückkehren, das sich nach der Analyse folgendermaßen präsentiert:

var a0_0x1844 = ["toUpperCase", "length", "fromCharCode", "Hallo SUS", "[a-z]", "charCodeAt"];

Offensichtlich ist, dass die an die Methode übergebenen numerischen Konstanten die Beschaffung von Werten aus dem Array ermöglichen.

Vertiefte Strings

Der von Haus aus deaktivierte Wert string-array-encoding entscheidet, wie die in diesem Array abzulegenden Zeichenketten verwurstet werden. Steht er auf True, so erfolgt die Kodierung mit Base64. Nutzen Sie stattdessen RC4, so wird der String noch stärker verfremdet. Leider ist die Beschaffung der Werte dann zwischen 30 und 50 Prozent langsamer. Zu guter Letzt gibt es den Wert string-array-threshold, der die Auslagerungswahrscheinlichkeit von Strings beeinflusst. Unser Obfuscator lagert von Haus aus nicht alle Strings aus. Das Programm führt stattdessen einen Zufallsgenerator aus, um nur manche Strings zu transpilieren. Der Sinn dieser Aufgabe ist, die doch performanceintensiven Aufrufe des Arrays so wenig wie möglich durchzuführen.

Angemerkt sei, dass mit empfindlichen Strings-Konstanten arbeitender Code den Wert unbedingt auf eins setzen muss. Die praktische Erfahrung lehrt, dass ein einmal ausgekommener Schlüssel nicht mehr einzufangen ist. Wenn ein Hacker auf ihre Kosten diverse Cloud-Services missbraucht, lernen sie das Fluchen in mehreren Sprachen. Erfreulicherweise setzt die Verbesserung der Sicherheit des Strings nur eine – vergleichsweise minimale – Anpassung der Parametrisierung voraus:

tamhan@TAMHAN14:~/SUSObfuscate$ javascript-obfuscator . --output ./subfolder --string-array-encoding base64
[javascript-obfuscator-cli] Obfuscating file: subfolder/worker.js...
[javascript-obfuscator-cli] Obfuscating file: worker.js...

Wer die Ausgabe des Obfuscators genau betrachtet, stellt fest, dass er auch die schon verfremdete Datei abermals bearbeitet. Das liegt daran, dass das Übergeben eines Verzeichnisnamens als Eingabe den Obfuscator prinzipiell dazu animiert, das Verzeichnis und alle seine Unterordner gleichermaßen zu bearbeiten.

Achten Sie deshalb darauf, vor jedem Aufruf des Obfuscators das Verzeichnis zu löschen, in dem sich die schon bearbeiteten Dateien befinden. Das lässt sich in einem Build-System beispielsweise über einen Kommandozeilenbefehl bewerkstelligen, der vor der eigentlichen Ausführung des Kompilationsprozesses abgefeuert wird.

Nach getaner Arbeit sieht der String jedenfalls wesentlich weniger übersichtlich aus:

var a0_0x4370=['dGVzdA==','ZnJvbUNoYXJDb2Rl',. . .

Beachten Sie, dass die nun verschlüsselt vorliegenden Strings vor der Verwendung bereitgestellt werden müssen. Diese Aufgabe nimmt Zeit in Anspruch, was insbesondere bei performancekritischem Code stört.

Angemerkt sei, dass ein Obfuscator – egal wie gut er auch arbeitet – niemals einhundertprozentige Sicherheit für Konstanten gewähren kann. Bedenken Sie, dass der Code ja im Browser des Clients ausgeführt werden muss. Die sensiblen Informationen müssen also irgendwann als dechiffrierter Klartext vorliegen. Ein Angreifer kann – ausreichende Motivation vorausgesetzt – diese notfalls bei der Übergabe an API und Co. abgreifen.

Fortgeschrittene Bösartigkeit

Bisher hatte sich JavaScript Obfuscator auf das Verkomplizieren der Struktur des vorliegenden Codes beschränkt. Das Programm ist allerdings auch in der Lage, Sicherheitsroutinen einzubauen, die Debuggern die Ausführung des Codes erschweren. Zudem gibt es Features, die die Ausführung auf fremden Domains verunmöglichen sollen.
Als ersten Versuch wollen wir versuchen den Code auf eine Domain zu beschränken. In der Theorie würde es ausreichen, einen domainLock-Parameter an den Obfuscator zu übergeben:

tamhan@TAMHAN14:~/SUSObfuscate$ javascript-obfuscator . . . --domainLock www.tamoggemon.com

An dieser Stelle zeigt sich ein interessanter Trend: Die Anbieter von Browsern und sonstigen Systemen versuchen, Killercode aktiv außer Gefecht zu setzen. Der Parameter zeigte sich in Tests des Autors unter Chrome und Firefox gleichermaßen wirkungslos. Dieses Katz-und-Maus-Spiel ist von Compilern im Embedded-Bereich hinreichend bekannt. Gehen Sie nicht davon aus, dass ein offensives Feature sechs Monate nach seiner Auslieferung durch den Obfuscator-Anbieter noch wie erwartet funktioniert. Leider funktioniert das in der Praxis – insbesondere bei sehr simplem Code – eher schlecht als recht. In Tests des Autors erschien die Meldung auch dann, wenn die übergebene Domain nicht korrekt war.

Ein weiteres offensives Mittel ist die debugProtection. Dahinter steckt der Gedanke, dass JavaScript Obfuscator Code in das Programm einfügt, der den Debugger auf die eine oder andere Art und Weise außer Gefecht setzt. Zur Nutzung dieser Funktion reicht es aus, den Wert im Rahmen des Durchlaufs auf True zu setzen:

tamhan@TAMHAN14:~/SUSObfuscate$ javascript-obfuscator . . . --debugProtection true

Auch hier zeigt sich der weiter oben besprochene Trend: In allen auf der Workstations des Autors installierten Browsern kam es bei aktivierter Option zwar zu höherem CPU-Ressourcenverbrauch, die Entwicklerwerkzeuge blieben – im Großen und Ganzen – jedoch funktionsfähig.

Zu guter Letzt möchte ich Ihnen noch zwei Optionsgruppen vorstellen, die tiefergehende Veränderungen am Quellcode vornehmen:

--control-flow-flattening <boolean>
--control-flow-flattening-threshold <number>
--dead-code-injection <boolean>
--dead-code-injection-threshold <number>

Bei Aktivierung von dead-code-injection fügt der Obfuscator toten Code in die Ausgaberoutinen ein. Der Hintergedanke davon ist, dass das verschönerte Programm dann immer noch extrem lang ausfällt, was die Analyse des Kontrollflusses erschwert. Auf der Sollseite steht die naturgemäß langsamere Ausführung des Codes.

Hinter control-flow-flattening verbirgt sich eine Option, die man aus dem Bereich der Mikrocontrollertechnik als Inlining kennt. Der Obfuscator ersetzt in diesem Fall Funktionsaufrufe durch den Code der Methode. Der Lohn der Mühen ist wesentlich größerer Programmumfang, der sich allerdings schwerer von Hand analysieren lässt. In beiden Fällen setzt das Programm Zufallsgeneratoren ein, um das Aktivieren des jeweiligen Features zu triggern. Desto höher der Wert des jeweiligen Thresholds, desto wahrscheinlicher ist das Auftauchen der jeweiligen Struktur. Angemerkt sei, dass sich der JavaScript Obfuscator nicht nur aus der Kommandozeile heraus aktivieren lässt. Das Entwicklerteam stellt auch Plug-ins für verschiedene Paketierungssysteme zur Verfügung.

Zum Zeitpunkt der Drucklegung gibt es Erweiterungen für webpack, Gulp und Grunt. Alle drei funktionieren im Prinzip analog – im Fall von webpack müssen Sie zur Installation beispielsweise folgendes npm-Kommando eingeben:

npm install --save-dev webpack-obfuscator

Im nächsten Schritt können Sie den JavaScript Obfuscator direkt aus webpack heraus aufrufen. Hierzu sind kleine Anpassungen in der Konfigurationsdatei erforderlich. Neben dem Laden des Plug-ins mittels require schreiben wir das resultierende Objekt in das plugins-Array:

var JavaScriptObfuscator = require('webpack-obfuscator');

// webpack plugins array
plugins: [
  new JavaScriptObfuscator ({
    rotateUnicodeArray: true
  }, ['excluded_bundle_name.js'])
],

In der Praxis ist es höchst ratsam, auf derartige Dienste zurückzugreifen. Es ist nur eine Frage der Zeit, wann ein Entwickler in der Hektik vergisst, die manuelle Obfuscation durchzuführen. Wie im Fall des weiter oben genannten Schlüssels gilt dann auch hier, dass einmal ausgekommener Code nicht wieder einzufangen ist.

Und jetzt in kommerziell

Das Team um Timofey Kachalov leistet im Bezug auf Support durchaus beachtliches – Issues werden schnell beantwortet, auch dumme Fragen bekommen eine freundliche Antwort. Insbesondere in sehr heiklen Situationen wünscht man sich mitunter ein komplett kommerzielles Unternehmen. In diesem Bereich hat sich Jscrambler als Klassiker herausgearbeitet. Das Produkt wurde von Gartner in verschiedenen Publikationen empfohlen.

Schon an dieser Stelle sei darauf hingewiesen, dass das Jscrambler-Team auf seiner Webseite keine Preisinformationen veröffentlicht. Angelsächsische Quellen nennen Einstiegspreise von $ 85 pro Monat für nicht näher definierte Start-ups. Die Verwendung dieses Produkts ist mit Sicherheit kein Angebot für kleine Entwickler.

Im Austausch dafür verspricht Jscrambler umfangreichen Codeschutz. Die Analyse hört nicht nach der Kompilation auf, sondern wird auch im Browser des Clients fortgeführt. Das Unternehmen verspricht, Manipulationen am DOM zu erkennen und abzuwehren. Das hilft zum Beispiel, wenn der Angreifer dem Programm per Debugger auf die Pelle rückt.

Wer die Software ausprobieren möchte, kann sich unter https://jscrambler.com/signup mit einem Mailaccount anmelden. Nach dem Abarbeiten der diversen Formulare ist die in Abbildung 5 gezeigte Weboberfläche zu sehen.

Abb. 5: Jscrambler implementiert ein vergleichsweise komplexes Benutzerinterface

Abb. 5: Jscrambler implementiert ein vergleichsweise komplexes Benutzerinterface

Die hier vorliegende Software unterscheidet sich von JavaScript Obfuscator insofern, als sie am Server ein neues Projekt anlegen müssen. Hierzu können Sie auf den Knopf Dashboard klicken. Der vom Entwickler von Haus aus angelegte Playground ist nur ein Beispielordner, über den Knopf Create App können Sie jederzeit eine eigene Applikation hinzufügen.

Im nächsten Schritt können Sie die auf Ihrer Workstation liegenden Informationen und Dateien hochladen. Beachten Sie, dass die Demoversion pro Projekt nur maximal 25 Files erlaubt. Im Interesse der Bequemlichkeit wollen wir unser soeben angelegtes Beispielprojekt an dieser Stelle recyclen. Beachten Sie, dass einige fortgeschrittene Schutzoptionen nur im Rahmen des Playgrounds zur Verfügung stehen.

Nach dem Hochladen der beiden Dateien finden Sie auf der rechten Seite des Bildschirms die Rubrik Applications Modes. Das Programm bietet von Haus aus eine Gruppe von Vorlagen an, die häufig verwendete oder für bestimmte Nutzungsszenarien geeignete Schutzfunktionen automatisch aktivieren. Wir wollen den folgenden Schritten die Option Web Browser App anklicken, sodass sie mit einem grünen Häkchen markiert ist.

Im nächsten Schritt können wir in die Rubrik Templates wechseln. Sie präsentiert sich wie in Abbildung 6 gezeigt. Beachten Sie, dass jede Option durch Anklicken eine Gruppe von Unterparametern auf den Bildschirm bringt.

Abb. 6: Der Obfuscator ist feingranular parametrierbar

Abb. 6: Der Obfuscator ist feingranular parametrierbar

Besonders lustig ist in diesem Zusammenhang die Funktion OS Lock, die den Code um Elemente anreichert, die bestimmte JavaScript Runtimes aus dem Tritt bringen. Zum Zeitpunkt der Drucklegung erlaubt man ein Anzielen der folgenden Betriebssysteme:

  • Linux
  • Windows
  • Mac OS
  • TiZen
  • Android
  • iOS

Nach der kompletten Konfiguration der auf die Codedatei anzuwendenden Schutzoptionen finden Sie auf der Unterseite des Bildschirms den Knopf Save Template. Dort können Sie einen Namen vergeben, unter dem die Parametersammlung später im Benutzerinterface ansprechbar ist.

Nach getaner Arbeit können sie auf den Knopf Protect App klicken, um den eigentlichen Prozess zu starten. Er liefert im Fall unseres kleinen Beispielprogramms das in Abbildung sieben gezeigte Resultat. Es ist offensichtlich, dass auch die primitiven Basiseinstellungen zu sehr schwer lesbarem Code führen (Abb. 7).

Abb. 7: Der Obfuscator hat seine Schuldigkeit getan

Abb. 7: Der Obfuscator hat seine Schuldigkeit getan

Beachten Sie in diesem Zusammenhang, dass die von der kostenlosen Testversion verschlüsselten Codedateien nur 24 Stunden nach der Transpilation zur Verfügung stehen und die Arbeit danach einstellen. Wer Code produktiv einsetzen möchte, muss unbedingt eine Vollversion erwerben.

Zum Deployment der erzeugten Dateien steht über die Option Download App ein Werkzeug zur Verfügung, dass ein Archiv mit allen hochgeladenen Inhalten bereitstellt. Wer die Inhalte näher analysiert, stellt fest, dass der Obfuscator aber auch die in HTML-Dateien befindlichen Inline-Elemente verschlüsselt – ein nicht unerheblicher Vorteil.

Fazit

Als Microsoft .NET herausbrachte, herrschte eine ähnliche Hysterie auf dem Markt: Entwickler gingen davon aus, ihr geistiges Eigentum zu verlieren. In der Praxis erwies sich die Situation als weniger kritisch. In der Welt von JavaScript dürfte die Situation bis zu einem gewissen Grad ähnlich sein. Wer sich Sorgen um wertvolle Algorithmen macht, findet mit den diversen Obfuscatoren Werkzeuge, die dem Angreifer das Leben erschweren. Wie so oft gilt auch hier das Sankt-Florian-Prinzip: Ihr Code muss nicht absolut unverwundbar sein. Es reicht völlig aus, wenn der Angreifer nach einem kurzen Blick beschließt, dass er lieber eine andere Applikation klont. In diesem Sinne: viel Spaß!

 

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -