Tests, die den ganzen Code prüfen
Worum geht es?
Ein gewöhnlicher Test prüft einen Fall, den wir schon kennen. Ein Meta-Test durchsucht den ganzen Code nach einem Muster und schlägt an, sobald etwas Neues es verletzt. So geht eine Sicherheitsregel nicht dadurch verloren, dass wir etwas Neues bauen.
Schutzziel
Sicherheitsregeln sollen auch für Code gelten, den es heute noch nicht gibt. Besonders wenn schnell gebaut wird, soll niemand versehentlich etwas einführen können, das eine Regel umgeht.
Funktionsprinzip
Statt zu prüfen, dass eine bestimmte Route abgesichert ist, prüft ein Meta-Test jede Route. Fehlt bei einer neuen die Absicherung, schlägt der Test fehl, und die Änderung wird nicht ausgeliefert. Beispiele für solche Muster:
- Jede Route hat eine ausdrückliche Entscheidung zur Zugriffsprüfung. Fehlt sie, wird die Anfrage auch zur Laufzeit abgelehnt.
- Jedes Textfeld, das Inhalte aufnimmt, ist als verschlüsselt eingetragen.
- Jede Tabelle mit Projektbezug wird vom Projektfilter erfasst, damit keine Abfrage über Projektgrenzen hinausreicht.
- Neue Inhaltstypen werden beim Löschen zunächst in den Papierkorb gelegt.
- Antworten enthalten nur Felder, die ausdrücklich freigegeben sind.
- Jede Rechteprüfung berücksichtigt den Kontostatus, und jede Ratenbegrenzung ist wirksam eingerichtet.
- Hierarchien, die auf sich selbst verweisen, lehnen Zyklen ab.
- Schreibende Anfragen sind gegen doppelte Verarbeitung abgesichert, falls eine Anfrage nach einem Verbindungsabbruch wiederholt wird.
- Texte für Nutzer laufen über Übersetzungsschlüssel.
Maßnahmen
- Wir bevorzugen Meta-Tests vor Einzelfall-Tests, wenn beides möglich ist, weil ein Muster eine ganze Fehlerklasse verhindert und ein Einzelfall nur den einen bekannten Fehler.
- Die Meta-Tests laufen bei jeder Änderung in der Prüfstrecke. Eine Änderung, die ein Muster verletzt, wird nicht ausgeliefert.
- Bei den Zugriffsprüfungen gibt es zusätzlich ein Gegenstück zur Laufzeit, das eine Route ohne Entscheidung ablehnt, auch wenn die Prüfstrecke nicht gelaufen wäre.
- Zu jeder neuen sicherheitsrelevanten Maßnahme gehört ein Test, bevor sie als fertig gilt.
Was wir nicht versprechen
- Meta-Tests finden nur Muster, die wir kennen. Neue Fehlerarten brauchen neue Muster.
- Sie zeigen, dass eine Prüfung vorhanden ist, nicht dass sie fachlich das Richtige prüft. Das Mutation-Testing schaut deshalb zusätzlich auf die Berechtigungsprüfungen.
- Sie ersetzen weder das Lesen des Codes durch Menschen noch einen unabhängigen Penetrationstest. Einen solchen hat es bisher nicht gegeben.
Wie wir das prüfen
Die Tabelle unten nennt die Meta-Tests. Ob unsere Tests Fehler in den Berechtigungsprüfungen bemerken würden, prüfen wir monatlich mit Mutation-Testing; das Ergebnis steht im Monatsbericht.
Nachweis-Tests
| Test | Das belegt der Test |
|---|---|
AuthorizationCoverageTest |
Jede Route der Anwendung hat eine ausdrückliche Entscheidung zur Zugriffsprüfung. |
EncryptionCoverageTest |
Textfelder, die Inhalte aufnehmen, sind als verschlüsselt eingetragen. |
TenantFilterCoverageTest |
Jede Tabelle mit Projektbezug wird vom Projektfilter erfasst. |
SoftDeleteCoverageTest |
Neue Inhaltstypen werden beim Löschen zunächst in den Papierkorb gelegt. |
SerializerGroupLeakageTest |
Antworten enthalten nur ausdrücklich freigegebene Felder. |
VoterUserStatusGateCoverageTest |
Jede Rechteprüfung berücksichtigt den aktuellen Kontostatus. |
RateLimiterLockCoverageTest |
Jede Ratenbegrenzung ist wirksam eingerichtet. |
SelfReferencingHierarchyCycleGuardTest |
Hierarchien, die auf sich selbst verweisen, lehnen Zyklen ab. |
GlobalIdempotencyCoverageTest |
Schreibende Anfragen sind gegen doppelte Verarbeitung bei einer Wiederholung abgesichert. |
NoHardcodedUserFacingStringsTest |
Texte für Nutzer laufen über Übersetzungsschlüssel. |
Änderungsverlauf
- : Erste Fassung.