Durch einen Post von @heluecht@pirati.ca wurde ich auf ein Problem im Quellcode der Luca-App aufmerksam: https://pod.geraspora.de/posts/13446160
Die zwei kritischen Code-Stücke sind für das Testen zuständig und man findet sie hier: https://gitlab.com/lucaapp/android/-/blob/master/Luca/app/src/main/java/de/culture4life/luca/ui/registration/RegistrationViewModel.java
Teil 1:
public boolean isUsingTestingCredentials() {
return Objects.equals(firstName.getValue(), "John")
&& Objects.equals(lastName.getValue(), "Doe")
&& Objects.equals(phoneNumber.getValue(), "+4900000000000")
&& Objects.equals(email.getValue(), "john.doe@gmail.com");
}
Teil 2:
boolean isValidPhoneNumber(String phoneNumberString) {
if (isUsingTestingCredentials()) {
return true;
}
try {...
Als Hackerin mit Codex will ich mich darüber nicht nur lustig machen sondern erklären worin das Problem liegt und wie man es beheben kann.
Sicherheitsverständnis bei Open-Source
Ein weit verbreitete Fehleinschätzung ist, dass Open-Source sicherer ist als geheimer proprietärer Quellcode. Niemand außer dem Besitzer kann geheimen Quellcode prüfen und deswegen können Fehler jahrelang unbemerkt bleiben und nur von Eingeweihten ausgenutzt werden. So kann man im geheimen Quellcode problemlos Hintertüren und andere Schweinereien verstecken.
Open-Source oder freier Quellcode kann von jedem eingesehen werden und so ist es schwieriger dort Hintertüren zu verstecken. Diese Schwierigkeit macht den offenen Quellecode schon mal ein bisschen sicherer. Dann muss dieser Quellcode aber immer noch getestet, überprüft und kontrolliert werden. Geschieht dies nicht und alle vertrauen nur blind auf die Sicherheit dann ist das sehr fahrlässig. Es gibt leider Beispiele wo offensichtliche Fehler im frei zugänglichen Quellcode jahrelang übersehen wurden - siehe: Heartbleed - https://de.wikipedia.org/wiki/Heartbleed
Jetzt muss man aber auch die Philosophie von freier Software verstehen und die wird nirgendwo an der Universität gelehrt. Die muss man sich per Selbststudium im Internet beibringen. Wenn jeder in den Quellcode schauen kann und er danach immer noch sicher ist, dann habe ich echte Sicherheit (immer vorausgesetzt, dass Experten auch drauf geschaut haben). Das heißt natürlich, dass ich nichts in den Quellcode schreiben darf was man später ausnutzen kann (weil dies würde die Sicherheit schwächen).
Leider lernt man an der Universität oder Ausbildung sogut wie nichts über Sicherheit, die schon beim Design der Software ansetzt. Dies sind relativ neue Forschungen und die Ausbildungskräfte bilden sich nicht gut genug fort als das sie darüber Kenntnisse hätten. Für Wirtschaftsinformatiker scheint es wichtiger zu sein, dass sie profitabel sind und nicht sicheren Quellcode schreiben (blöder Kapitalismus).
Was ist hier das Problem?
Am oben gezeigten Quellcode sieht man, dass getestet wird. So was nennt man Test-Driven-Development und das ist zunächst etwas Gutes. Der Quellcode wird vor dem "Build" also dem zusammenbauen als fertige App zunächst automatisiert getestet und wenn ein Test fehlschlägt wird der "Build" abgebrochen, sodass der Fehler korrigiert werden muss. Der Fehler kann wenn er durch den Test erkannt wird also nicht beim Endbenutzer auftauchen.
Wie man aber in Teil 2 oben sieht kann man mit den Testdaten Prüfungen in der App umgehen und dadurch mehr Rechte erhalten. Noch viel schlimmer ist, dass wir in Teil 2 sehen, das der "try"-Teil erst nach der Prüfung auf Testdaten startet. "Try" ist für die Fehlerbehandlung zuständig und das bedeutet ich kann mit Testdaten die App in einen undefinierten Zustand bringen, weil es keine Fehlerbehandlung gibt. Diese undefinierten Zustände können Hacker häufig für Exploits ausnutzen.
Insgesamt also alles sehr schlecht!
Wie kann ich das besser machen?
1) Compilerflags - Mit Compilerflags kann ich verhindern, das bestimmte Programmteile in der produktiven App landen. Vereinfacht gesagt ich baue mir eine Testversion und wenn die funktioniert dann baue ich mir eine Produktivversion wo die Testfunktionen nicht enthalten sind. Großer Nachteil dieser Methode ist, das Programmierer gelegentlich vergessen, die Testfunktionen richtig rauszulöschen mit den Flags weil sie zu sehr unter Druck stehen und dann Fehler machen. So ist es häufiger schon passiert, dass unbeabsichtigt Testfunktionen doch im Produktivsystem gelandet sind. Ein weiteres Problem ist wenn Fehler nicht in der Testversion auftreten aber im Produktivsystem weil es anders gebaut wurde. Dann sind wahrscheinlich irgendwo die Compilerflags falsch gesetzt worden. Ein Fehler den man dann niemals machen darf, der aber schon passiert ist, ist, dass dann einfach die Testversion ausgeliefert wird in der Hoffnung, dass das niemand merkt.
2) Testflags verwenden - In der Testumgebung wird über die Konfiguration ein bestimmtes Flag gesetzt, sodass die Software weiß, dass sie im Testmodus ist. Nachteil ist, dass bösartige Hacker diese Flag auch in der Produktivumgebung setzen könnten.
3) So Testen, dass es keinen Unterschied macht (beste Lösung). Warum im Testsystem nicht mit anonymisierten oder pseudonymisierten Daten so testen wie unter echten Bedingungen? Meistens macht das etwas mehr Aufwand aber dafür hat man die Tests unter Echtbedingungen gemacht was den höchsten Wert hat. Keine Flags oder Funktionen im Quellcode die ausgenutzt werden könnten.
#luca #software #testen #test #sicherheit #problem #bildung #entwicklung #verstädnis #lernen #hack #hacking #app #smartphone #gesundheit #corona #programm