Wie schützt man sich vor supply-chain Angriffen?

Aus aktuellem Anlass gibt’s mal wieder Debatten über supply-chain-Angriffe.

Wie schützt man sich davor? Die ernüchternde Antwort: Man kann sich davor nicht schützen.

Im Detail:

Was ist ein supply-chain-Angriff? Der einfache Fall sei so erklärt: Man stelle sich vor, man entwickelt eine Software A. Darin verwendet man eine Library B. Nun will ein Angreifer seine Malware verteilen, zum Beispiel in A. Das ist aber schwierig, weil die Entwickler von A eine hohe awareness haben, die Build-Server sind alle abgesichert und haben alle Securty updates und long story short: Ein Angreifer kann A nicht oder nur mit hohem Aufwand hacken. Angreifer suchen sich aber typischerweise den Weg des geringsten Widerstands. Wenn Angreifer also wissen, dass B in A verwendet wird, und B ein leichteres Angriffsziel ist, dann hacken sie B, schleusen ihre Malware in B ein, und die wird dann in A später ausgeführt. Das kann für Angreifer auch deshalb lukrativ sein, weil wenn B nicht nur von A sondern auch von 1000 anderen Produkten verwendet wird, dann wird die Malware, wenn sie nicht schnell entdeckt wird, in 1000 Produkten publiziert. Das ist also auch eine einfache Skalierungsmethode.
Jedenfalls basiert der Angriff darauf, dass man nicht den Quellcode von dependencies (also libraries oder andere Arten von Softwares, die man verwendet) prüfen kann.

Warum kann man nicht einfach den Quellcode prüfen? Es gibt mehrere wichtige Gründe:

  1. Es ist unpraktikabel. Man muss bei jedem Update den Quellode der library prüfen. Diese Lirbrary hat wiederum andere Abhängigkeiten, die auch geupdatet werden können, und diese Abhängigekeiten muss man dann auch reviewn. Das macht so unfassbar viel Arbeit, dass wenn man das tatsächlich durchzieht, dann wird man frühestens fertig, wenn von der Library schon wieder mehrere neuere Versionen mit noch mehr Änderungen erschienen sind.
  2. Der Quellcode im repository muss nicht mit dem Code, der tatsächlich ausgeliefert wird, übereinstimmen. Siehe CVE-2024-3094 als Beispiel. Das heißt man muss npm-Pakete mit minifitem Javascript reviewn. Oder man muss bei Programmiersprachen, die kompiliert werden, den Quellcode erst noch dekompilieren. Ob das lizenzrechtlich erlaubt ist, ist nochmal eine ganz andere Frage. Und bei closed source dependencies hat man ohnehin keine andere Möglichkeit, das zu reviewn, als die ausgelieferten Pakete zu analysieren. Aber das ist halt auch keine Lösung, weil das macht das review, das aufgrund von 1. sowieso schon zu komplex ist, nur noch schwerer.

Also wir halten fest: Reviews sind keine Lösung um sich gegen supply-chain-Angriffe zu schützen.

Reviews sind generell gut und wichtig, um 99% der Sicherheitslücken zu finden, nämlich die Sicherheitslücken, die vom Entwickler selbst ungewollt beim Entwickeln in den source-code kommen.

Aber bei supply-chain-Angriffen kann man sich nicht schützen, weil die Angriffsfläche nicht im eigenen Verantwortungsbereich liegt. Das macht es so schwierig. Man muss drauf vertrauen, dass die Entwickler der dependencies, die man verwendet, sich genau so gut um Sicherheits kümmern wie man selbst. Das funktioniert mal mehr mal weniger gut leider. Man kann ein bisschen drauf achten, dass man dependencies wenn möglich von Lieferanten bezieht, die vertrauenswürdig wirken. Beispiele für Kriterien sind:

  • Teamgröße: Leider gibt es viele Entwickler-teams, die nicht genug Zeit haben, weil der Chef am Budget für Mitarbeiter spart oder weil man als open-source-Entwickler für seinen Projekt zu wenig community-support bekommt. Da ist dann das review von Änderungen oft weniger gut oder bleibt ganz weg, oder – wie im Fall von CVE-2024-3094 – ein bösartiger Entwickler übernimmt da das Ruder.
  • Produkt-Herkunft: Es gibt, und das ist nunmal Fakt, gewisse Länder, in denen eher Malware verbreitet wird als in anderen. Es gibt einige Länder, die IT-Teams haben, die im staatlichen Auftrag hacken. Klingt wie eine Verschwörungstheorie, ist aber real. Und da ist das bereitstellen von Malware unter dem Deckmantel einer nützlichen Software natürlich eine einfache Methode überall auf der Welt seine Malware zu verbreiten.
  • Verdienst: Steht hinter einer Software eine Firma, deren Haupt-Zweck es ist, dmait Geld zu verdienen? Tendenziell gut. Ist unklar, wie die Maintainer Geld verdienen? Tendenziell unklar. Nur als einfaches Beispiel: Große Firmen wie Microsoft und co. können jederzeit z. B. mit einem Windows-update Malware verbreiten. Machen Sie aber nicht. Warum? Weil sie auf legalem Weg genug Geld verdienen. Da wird es unattraktiv, seine Nutzer zu vergraulen, indem sie Malware bekommen. Weil wenn die Nutzerzahlen sinken, sinkt auch das legal erwirtschaftete Einkommen und je größer die Firma ist, desto weniger lohnt sich das. Man kann es ein oder vielleicht auch zwei mal machen, aber dann ist man seinen vertrauenswürdigen Namen auch verbrannt. Und je mehr legal erwirtschaftetes Geld da dran hängt, desto mehr ist man auch gewillt, für seine Sicherheit zu investieren, damit Angreifer nicht einfach den Buildserver hacken.
  • Reputation: Je mehr reputation in Form von z. B. GitHub-Sternen ein Projekt hat, desto eher ist die Wahrscheinlichkeit, dass es ein “gutes” Produkt ist, bei dem die Maintainer auch ein bisschen auf die Sicherheit achten.

Bedenke: Das sind alles nur soft Kriterien um am Ende eine Abwägung zu treffen. Nach allen kriterien kann eine Software vertrauenswürdig sein und dennoch der Ausgangspunkt eines suply-chain-Angriffs sein. Die Wahrscheinlichkeit ist nur geringer.

Wie die Malware oder auch nur die Sicherheitslücke letztendlich in die dependency kommt, ist völlig egal. Es kann social engineering sein, es kann klassisches “reinhacken” sein, es kann ein andereer Weg sein: In allen Fällen ist es für den Nutzer der infizierten Software das gleiche Problem.

Das Problem ist auch nicht nur auf libraries als dependency beschränkt. Natürlich können auch executables oder gar Services Malware bekommen und damit dann andere Nutzer dieser Software dahingehend infizieren, dass weitere Software infiziert wird. Letztendlich würde man das alles mehr oder weniger supply-chain-Angriff nennen.

Man wird sich Lösungen dafür ausdenken, um die Software-Lieferkette signifikant sicherer zu machen. Es ist aber leider extrem schwer und bislang gibt es daher noch keine etablierten best-practices, um sich davor zu schützen. Ich denke aber nicht, dass dieser unangenehme Zustand ewig so bleibt. Bisher hat man für größere Probleme in der IT meistens gute Lösungen gefunden, und es bleibt zu hoffen, dass das bei Supply-chain-Angriffen auch so sein wird. Bis dahin ist Vorsicht bei der Wahl der dependencies geboten und man muss achtsam die Nachrichten über die benutzten dependencies verfolgen um bei Bedarf schnell handeln zu können, um zumindest im Fall der Fälle die Auswirkungen möglichst gering zu halten.