Parasoft C/C++test 2022.2 unterstützt das neue MISRA C:2012 Amendment 3 und eine Entwurfsversion von MISRA C++ 202x. Erfahren Sie mehr >>

Sichere Codierungsstandards: Durchsetzung sicherer Codierungspraktiken mit SAST

Von Kevin E. Greene

2. September 2021

9  min lesen

Wenn Entwicklungsteams verwenden sichere Codierungsstandards Bei der Entwicklung von Software sind das Ergebnis weniger Sicherheitsfehler und letztendlich eine bessere Qualität, die zu einer robusteren Erfahrung für Entwickler und Benutzer gleichermaßen führt. In diesem Blog gehen wir auf die Grundlagen sicherer Codierungsstandards, Best Practices und deren Verwendung ein.

So funktioniert sichere Codierung

Sichere Codierung bedeutet, dass Entwickler eine Reihe von Codierungsstandards oder Richtlinien für sichere Codierung anwenden, die sie im Quellcode implementieren, um gängige Schwachstellen zu verhindern und zu mindern, die oft zu Cyberangriffen führen. Die Implementierung sicherer Codierungspraktiken in Code ist die erste Verteidigungslinie, die vor bösartigen Akteuren schützt, die Software ausnutzen, und die Angriffsflächen eliminiert, auf die Angreifer häufig mit Malware abzielen. Wenn Unternehmen sich konsequent an die bewährten Verfahren zur sicheren Codierung halten, können sie die Kosten für die Wartung von Software senken und Entwickler können mehr Zeit für Innovationen aufwenden, anstatt Zeit für Fehlerbehebungen aufzuwenden.

Sichere Codierungspraktiken stellen sicher, dass Sicherheitskontrollen im Code implementiert sind, um Sicherheitsprobleme zu reduzieren, die sich als Folge von schlecht entwickeltem Code manifestieren können. Es ist zwingend erforderlich, dass Unternehmen sichere Codierungspraktiken formalisieren, um einen Mindestsatz von Softwaresicherheitsstandards für das Schreiben von Code durch Entwickler festzulegen, die die Organisation mit automatisierten . durchsetzen und validieren kann statische Analyse or Statische Anwendungssicherheitstests (SAST) Werkzeuge. Diese Tools verwenden Regeln und Checker, die Quellcode auf Syntaxverletzungen, undefinierte Variablen, Codequalität, Codierungs- und Sicherheitsverletzungen sowie Programmierfehler (um nur einige zu nennen) analysieren.

Erste Schritte mit der statischen Analyse

Die statischen Analysetools von Parasoft verwenden sichere Codierungsstandards wie CERT Codierungsstandards, OWASP Top 10 (Teil der OWASP Secure Coding Guidelines), MITRE Common Weakness Enumeration (CWE), Und DISA Anwendungssicherheit und Entwicklung STIGS in Regeln und Checkern wie in Tabelle 1 gezeigt.

CodierungsstandardnameInstandgehalten vonZweckzusammenfassung
CERT (Computer Emergency Response Team)CERT-KoordinierungszentrumRichtlinien, die Entwicklern helfen, Fehler während der Codierung und Implementierung zu vermeiden und auch Fehler auf niedriger Ebene im Design zu erkennen.
OWASP Top TenOWASP-Stiftung (Open Web Application Security Project).Webanwendungs- und Softwareentwickler verwenden diese Standards, um Hochsicherheitsrisiken in Webanwendungen zu erkennen und zu beheben.
CWE (Common Weakness Enumeration)Gemeinschaft entwickelt und gepflegt.Dies ist ein Kategoriensystem, das Entwicklern hilft, Schwachstellen und Schwächen in Software zu identifizieren und ihnen hilft, Softwarefehler zu verstehen. Entwickler verwenden das System auch, um Tools zu entwickeln, um Fehler zu beheben und zu verhindern.
DISA Anwendungssicherheit und Entwicklung STIGSDefense Information Systems Agency (DISA) und Abteilung des US-Verteidigungsministeriums.Hilft Managern, Designern, Entwicklern und Systemadministratoren bei der Entwicklung und Pflege von Sicherheitskontrollen in Anwendungen und Anwendungsentwicklung.

Schlechte Codierungspraktiken führen zu Sicherheitsproblemen

Entwickler müssen sich der Konsequenzen ihrer Codierungs- und Refactoring-Aktivitäten beim Erstellen und Aufdecken von Schwachstellen in Software bewusst sein. Im Folgenden sind einige häufige Fehler aufgeführt, die schief gehen können, wenn Entwickler sichere Codierungspraktiken nicht befolgen und verwenden. Wir verfolgen Best Practices zur Minderung und Behebung dieser Sicherheitsprobleme.

Problem: SQL-Injection

Dies geschieht, wenn ein Angreifer auf unsichere Weise Eingaben in eine SQL-Abfrage einfügt, oft über eine einfache String-Kette. SQL-Injection ist ein hochgefährliches Sicherheitsrisiko für Anwendungen, da es relativ leicht zu missbrauchen ist und dazu führen kann, dass der Angreifer die gesamte Datenbank ändert, bereinigt oder stiehlt. Die Angreifer können die Anwendung auch verwenden, um gefährliche Befehle auf dem Betriebssystem auszuführen, das die Datenbank hostet, wodurch sie Zugang zu Ihrem Netzwerk erhalten.

Problem: Fehlerhafte Authentifizierung und Sitzungsverwaltung

Entwickler implementieren häufig Anwendungsaufgaben im Zusammenhang mit der Sitzungsverwaltung und -authentifizierung falsch. Auf diese Weise können Angreifer Schlüssel, Passwörter und Sitzungstoken kompromittieren und den Angreifern ermöglichen, Benutzeridentitäten zu ihrem Vorteil zu nutzen.

Problem: Fehlerhafte Zugriffskontrolle

Systeme setzen häufig nicht korrekt durch, was authentifizierte Benutzer tun dürfen. Böse Akteure können solche Fehler nutzen, um Zugriff auf Funktionen und Daten zu erhalten, beispielsweise auf Benutzerkonten und Dateien, um Daten zu ändern oder Zugriffsberechtigungen zu ändern.

Problem: Cross-Site-Scripting (XSS)

Dies tritt immer dann auf, wenn die Anwendung verdächtige Daten ohne ordnungsgemäße Authentifizierung auf einer neuen Webseite zulässt. XSS ermöglicht es Hackern, Skripte im Browser des Ziels zu implementieren. Die Skripte können Websites zerstören oder Benutzer an böswillige senden und Benutzersitzungen befehligen.

Beste Sicherheitscode-Praktiken

Die Zunahme von Cyberangriffen, die auf schlecht entwickelte Software zurückzuführen sind, macht es unerlässlich, dass Entwickler sichere Codierungspraktiken einhalten. Wenn dies der Fall ist, wird die Produktivität verbessert und die Softwarebereitstellung beschleunigt, da weniger Sicherheitsprobleme zu lösen sind. Dies erhöht die Wahrscheinlichkeit, dass der Build bestanden wird. Wenn ein Build bestanden wird, bedeutet dies, dass alle kritischen und hohen Schweregrade behoben wurden und kein signifikantes Risiko für das Unternehmen besteht. Zum Beispiel könnte eine Organisation Schwellenwerte (in Bezug auf den Schweregrad) definieren und/oder spezifische Probleme identifizieren, die nicht verhandelbar sind, und wenn sie identifiziert werden, wird der Build unterbrochen, bis die Probleme behoben sind.

Eine Möglichkeit, um sicherzustellen, dass ein Build erfolgreich ist, besteht darin, sichere Codierungspraktiken und eine Compliance-Validierung mit statischer Analyse im Rahmen automatisierter Tests durchzusetzen. Im Folgenden sind bewährte Sicherheitspraktiken aufgeführt, die Entwickler als Teil der sicheren Codierung befolgen können.

So verringern Sie die SQL-Injektion

Sichere Konfiguration verwenden

Häufig enthalten Datenbankverwaltungssysteme keine standardmäßig sichere Komponente. Entwickler müssen sicherstellen, dass die Sicherheitskontrollen in der Hosting-Plattform und im Database Management System (DBMS) funktionieren und richtig konfiguriert sind. Für die gängigsten DBMS existieren Leitfäden, Standards und Benchmarks. Der Datenbank-Spickzettel bietet eine schnelle Anleitung zum Entwickeln einer sicheren Konfiguration.

Verwenden Sie die sichere Authentifizierung

Alle Zugriffe auf eine Datenbank ordnungsgemäß authentifizieren. Verwenden Sie eine sichere Methode, um das DBMS zu authentifizieren. Authentifizieren Sie sich nur über einen sicheren Kanal und sichern Sie die Anmeldeinformationen ordnungsgemäß, bevor Sie sie zur Verfügung stellen. Weitere Informationen finden Sie im Datenbank-Spickzettel.

Verwenden Sie sichere Kommunikation

Fast alle DBMS unterstützen eine Reihe von Methoden zur Kommunikation, wie APIs, Dienste usw., sowohl unsicher (unverschlüsselt oder nicht authentifiziert) als auch sicher (verschlüsselt oder authentifiziert). Für Entwickler ist es ratsam, nur die sicheren Kommunikationsoptionen zu verwenden, die mit Protect Data Everywhere verfügbar sind (siehe unten). Der Datenbank-Spickzettel bietet schnelle Hilfe bei der Bereitstellung einer sicheren Kommunikation.

So vermeiden Sie fehlerhafte Authentifizierung und Sitzungsverwaltung

NIST 800-63b definiert drei Ebenen für die Authentifizierungssicherheit, auch bekannt als AAL oder Authentifizierungssicherheitsebenen.

Ebene 1: Passwörter

Stufe 1 ist für Apps mit geringem Risiko, die keine PII (persönliche identifizierbare Informationen) enthalten. Es erfordert nur eine Single-Faktor-ID, normalerweise ein Passwort.

Zu den Best Practices gehören:

  • Verwendung von Passwörtern mit nicht weniger als 8 Zeichen, wenn wir MFA (Multi-Faktor-Authentifizierung) verwenden; 10 Zeichen, wenn wir keine MFA verwenden.
  • Verwendung aller druckbaren ASCII-Zeichen zusätzlich zum Leerzeichen.
  • Werbung mit langen Passphrasen und Passwörtern.
  • Entfernen von Komplexitätsanforderungen (Entwickler haben festgestellt, dass sie nicht sehr effektiv sind).
  • Vermeiden Sie die Verwendung allgemeiner Passwörter, insbesondere derjenigen, die zuvor kompromittiert wurden.
  • Passwortwiederherstellung, die MFA-Elemente implementiert.
  • Sichere Speicherung von Passwörtern durch kryptografische Kontrollen.

Stufe 2: Multifaktor-Authentifizierung

Diese Stufe ist für Apps mit höherem Risiko, die PII enthalten, die Benutzer online bereitgestellt haben. AAL Level 2 erfordert MFA, einschließlich QTP-Implementierung (Quick Test Professional). MFA bescheinigt, dass ein Benutzer der ist, für den er sich ausgibt, und verlangt, dass sich die Person mit zwei oder mehr dieser Kombinationen identifiziert:

  • Eine PIN oder ein Passwort
  • Ein Telefon oder Token
  • Biometrie, wie ein Fingerabdruck oder ein Gesichtsbild

Stufe 3: Kryptografiebasierte Authentifizierung

Wenn ein betroffenes System zu erheblichen finanziellen Verlusten, persönlichen Schäden, strafrechtlichen oder zivilrechtlichen Verstößen oder erheblichem Schaden für das öffentliche Interesse führen kann, ist eine Authentifizierung der Stufe 3 erforderlich. Entwickler verwenden normalerweise kryptografische Module, um dieses hohe Maß an Sicherheit zu erreichen.

Sitzungsverwaltung

Eine Anwendung kann die Authentifizierung für einen begrenzten Zeitraum verfolgen. Dadurch kann der Benutzer die Anwendung weiterhin verwenden, ohne sich bei jeder Anfrage erneut authentifizieren zu müssen. Dies zu verfolgen wird als Sitzungsverwaltung bezeichnet.

Sitzungsgenerierung und -ablauf

Das System verfolgt den Benutzerstatus während einer Sitzung. Der Server speichert die Sitzung und fügt dem Benutzer eine Sitzungskennung hinzu, damit die Benutzerinformationen die Sitzung identifizieren können, die die richtigen Daten für den Benutzer enthält. Der Client verwaltet lediglich die Kennung, die auch vertrauliche serverseitige Sitzungsinformationen vom Client abschirmt.

Zu den Sicherheitskontrollen, die beim Implementieren oder Erstellen von Sitzungsverwaltungssystemen zu berücksichtigen sind, gehören:

  • Stellen Sie sicher, dass die Sitzungs-ID eindeutig, lang und zufällig ist.
  • Sicherstellen, dass die Anwendung eine neue Sitzung generiert oder zumindest die Sitzungs-ID während der Authentifizierung und erneuten Authentifizierung rotiert.
  • Stellen Sie sicher, dass die Anwendung nach einer Zeit der Inaktivität eine Leerlaufzeitüberschreitung implementiert, zusätzlich zum Festlegen einer maximalen Lebensdauer für jede Sitzung. Danach muss sich der Benutzer erneut authentifizieren.
Cookies

Anwendungen verwenden häufig Browser-Cookies, um Sitzungskennungen von Webanwendungen zu speichern, wenn Systeme Sitzungsverwaltungsmethoden implementieren. Einige Abwehrmaßnahmen sind:

  • Nur wenige Domains sollen auf die Cookies zugreifen können. Die Anwendung sollte ihre Pfade mit Tags versehen, damit die Tags am Ende oder kurz danach ablaufen, wenn die Sitzung ihre Vitalität verliert.
  • Setzen der „sicheren“ Tags, um sicherzustellen, dass das System nur auf einem sicheren Kanal überträgt.
  • Setzen des HttpOnly-Flags, um zu verhindern, dass JavaScript auf das Cookie zugreift.
  • Hinzufügen von „Samesite“-Eigenschaften zu Cookies, wodurch einige aktuelle Browser daran gehindert werden, Cookies mit standortübergreifenden Anforderungen zu senden. Dies schützt vor Angriffen durch Informationslecks und standortübergreifender Nachfragefälschung.
Tokens

Bei einigen Authentifizierungstypen können serverseitige Sitzungen einschränkend sein. „Stateless Services“ ermöglichen es dem System, Sitzungsdaten zu verwalten, um die Leistung zu verbessern. Das Ergebnis ist, dass der Aufwand für die Überprüfung und Speicherung von Benutzersitzungen auf dem Server geringer ist. Eine „zustandslose“ Anwendung erstellt ein temporäres Zugriffstoken, das das System verwendet, um die Anfrage eines Clients abzüglich der Anmeldeinformationen des Benutzers nach der ersten Authentifizierung zu authentifizieren.

JSON-Web-Token (JWT)

Dies ist ein offener Standard. Es ist eine eigenständige, kompakte Methode zur sicheren Übertragung von Informationen zwischen Entitäten als JSON-Element (JavaScript Object Notation). Das System kann die Informationen verifizieren, da sie digital signiert sind. Während der Authentifizierung erstellt das System ein JWT-Token und der Server überprüft es, bevor eine Verarbeitung stattfindet.

Der Server speichert das JWT nicht immer. Das System behält die Integrität des Tokens mit einer digitalen Signatur bei, sodass ein späterer Server bestätigen kann, dass das JWT gültig bleibt und dass es seit der Erstellung des Tokens durch das System nicht beschädigt wurde.

Diese Methode ist portabel und zustandslos, was bedeutet, dass die Server- und Client-Technologien unterschiedlich sein können, aber dennoch interagieren können.

So verringern Sie ungeschützte Daten

Gehen Sie wie folgt vor, um ungeschützte Daten zu vermeiden:

  • Klassifizieren Sie die Informationen in der Anwendung nach der Vertraulichkeitsstufe und ordnen Sie jede Datenkategorie der entsprechenden Schutzregel zu.
  • Verschlüsseln Sie Daten während der Übertragung. Zum Schutz von Webanwendungsdaten über ein Netzwerk verwenden Entwickler üblicherweise richtig konfigurierte TLS (Transport Layer Security).
  • Daten im Ruhezustand verschlüsseln. Vermeiden Sie, wenn möglich, sensible Informationen zu speichern. Wenn Sie es jedoch speichern müssen, schützen Sie es unbedingt kryptografisch.
  • Sichere lokale Speicherung in mobilen Geräten. Menschen stehlen oder verlieren oft mobile Geräte, wodurch die darin enthaltenen Informationen anfällig für Datenlecks werden. Besitzer müssen auf ihren Geräten ein Minimum an sensiblen Daten speichern und sie im angegebenen Datenspeicherverzeichnis speichern.
  • Lebenszyklen von geheimen Schlüsseln verwalten. Entwickler verwenden geheime Schlüssel in Anwendungen für vertrauliche Funktionen; B. zum Schutz von Kreditkarten und zum Signieren von JWTs. Verwalten Sie Schlüssel richtig, indem Sie:
    • Stellen Sie sicher, dass alle geheimen Schlüssel vor unbefugter Verwendung geschützt sind.
    • Verwenden unabhängiger Schlüssel, wenn mehrere Schlüssel benötigt werden.
    • Schlüssel richtig in geheimen Tresoren aufbewahren.
    • Erstellen von Anwendungen zum Ändern von Schlüsseln und Algorithmen bei Bedarf.
    • Erstellen von Features für die Schlüsselrotation.
  • Anwendungsgeheimnisse verwalten. Anwendungen haben viele „Geheimnisse“, die die Anwendungen für den sicheren Betrieb benötigen, wie Kennwörter, Zertifikate und Verschlüsselungsschlüssel. Wenn jemand diese Geheimnisse kompromittiert, kann dies zu einem kompletten Systemausfall führen. So verwalten Sie Anwendungsgeheimnisse:
    • Übergeben Sie sie nicht über Umgebungsvariablen oder speichern Sie sie in Konfigurationsdateien oder Code.
    • Bewahren Sie sie sicher in geheimen Tresoren auf.

Um gebrochene Zugriffskontrollen zu mildern

Entwickler können während der Entwurfsphase die folgenden Zugangskontrollmaßnahmen berücksichtigen:

  • Beziehen Sie die Zugangskontrolle von Anfang an ein. Lassen Sie auch die Anpassung zu.
  • Erzwingen Sie, dass alle Anforderungen die Zugriffskontrollprüfungen bestehen.
  • Verweigern standardmäßig. Wenn das Programm die Anfrage nicht ausdrücklich zulässt, lehnen Sie sie ab.
  • Implementieren Sie das „Prinzip der geringsten Berechtigung“. Stellen Sie sicher, dass alle Programme, Prozesse und Benutzer so wenig Zugriff wie möglich erhalten.
  • Rollen Sie keine Rollen fest. Zu viele Programme verwenden standardmäßig die rollenbasierte Zugriffssteuerung, die anfällig ist und keine Mandantenfähigkeit sowie horizontale und datenspezifische Zugriffssteuerungsregeln zulässt. Es ist auch schwer zu auditieren.
  • Protokollieren Sie jeden Fehler bei der Zugriffssteuerung. Diese können auf Exploits hinweisen, die die Anwendung nach Schwachstellen durchsuchen.

Minderung von Cross-Site-Scripting (XSS)

Escaping und Encoding sind Verteidigungsmethoden, die helfen, Injection-Hacks zu stoppen. Escaping bedeutet, dass der Codierer ein bestimmtes Zeichen vor der Zeichenfolge hinzufügt, um zu verhindern, dass sie falsch interpretiert wird. Sie können beispielsweise einen umgekehrten Schrägstrich ( \ ) vor einem doppelten Anführungszeichen ( “ ) einfügen, damit das System ihn als Text und nicht als Signal zum Schließen einer Zeichenfolge interpretiert. Kodierung, auch Ausgabekodierung genannt, bedeutet, dass der Entwickler Sonderzeichen in eine andere, aber gleiche Form umwandelt, sodass sie im Interpreter nicht gefährlich werden. Ändern Sie zum Beispiel < in die Zeichenfolge <, wenn Sie in HTML schreiben.

Andere Methoden des Injektionsschutzes umfassen kontextbezogene Ausgabecodierung, die Codierungsentwickler implementieren, wenn sie eine Benutzeroberfläche erstellen; Neutralisieren bestimmter Metazeichen, wenn Sie einem Befehl eines Betriebssystems Eingaben hinzufügen; Unicode-Kodierung, eine Methode zum Speichern von Zeichen mit mehreren Bytes; und Kanonisierung, bei der Systeme Daten in eine Standard- oder einfache Form umwandeln.

Wie Static Application Security Testing (SAST) Entwicklern bei der Verbesserung ihrer Programmierpraktiken hilft

Softwareentwickler verwenden SAST (statische Anwendungssicherheitstests), um automatisierte Tests auszuführen, um Quellcode zu analysieren, ohne den Code auszuführen oder auszuführen. Das Ziel besteht darin, Codierungsverletzungen und -schwächen zu identifizieren, die Software-Schwachstellen aufdecken könnten. SAST gilt als „White-Box“-Testansatz, da es Zugriff auf Quellcode hat, der das Design, das Framework und die Implementierung des Systems und/oder der Anwendung dokumentiert.

SAST verwendet die im Quellcode dokumentierten Details zusammen mit seiner Codestruktur, um die Einhaltung sicherer Codierungsstandards und -richtlinien sicherzustellen. SAST verwendet Regeln und Prüfer, um die Einhaltung von Richtlinien durchzusetzen und zu validieren sowie um Codierungsverstöße in den Codierungspraktiken von Entwicklern zu lokalisieren. Entwicklungsteams können zu Beginn des Entwicklungsprozesses verschiedene sichere Codierungsstandards und Richtlinien wie CERT Secure Coding Standards und CWE verwenden, um sicherzustellen, dass die Software bestimmte Qualitäts- und Sicherheitsanforderungen erfüllt.

Es sollte beachtet werden, dass leistungsstarke und ausgereifte Softwareentwicklungsorganisationen diese Standards und Praktiken verwenden, um Sicherheitsrichtlinien und Governance für Entwicklungsteams anzupassen. Viele Organisationen fügen zusätzliche Anleitungen hinzu, die sie für die Schulung und Sensibilisierung der Entwickler verwenden können. OWASP Top 10 und die sieben verderblichen Königreiche spielen eine Schlüsselrolle bei der Sensibilisierung für Dinge, die bei der Codierung schief gehen könnten.

Da SAST keine Ausführung der Software erfordert, um eine Analyse durchzuführen, können Entwickler sie nahtlos in ihre bestehenden Entwicklungsworkflows implementieren, um Code in Echtzeit zu analysieren und sofort alle Codierungsverletzungen zu melden, die von Codierungsregeln und -prüfungen ausgelöst werden. Das Ergebnis ist das Auffinden kritischer Qualitäts- und Sicherheitsprobleme im Workflow des Entwicklers, wo die Kosten für die Behebung und Behebung von Sicherheitsproblemen am günstigsten sind. Dies führt zu qualitativ hochwertigerer Software mit weniger Sicherheitsproblemen oder Schwachstellen, sodass Unternehmen Vertrauen in die Beschleunigung der Softwarebereitstellung und -bereitstellung gewinnen können.

Während die Integration von SAST in Entwicklerworkflows Entwicklern hilft, ihre Codierungsverletzungen zu erkennen, kann SAST auch nahtlos in eine automatisierte Pipeline integriert werden, um Code-Commits zu analysieren, bevor die Software in die Produktion geht. Jeder Commit kann automatisch einen Scan von einem SAST-Tool auslösen.

Parasoft SAST-Tools nutzen KI/ML für inkrementelles Scannen, das nur Code analysiert, der sich im Rahmen dieses Commits geändert hat. Dies ermöglicht eine effizientere Nutzung von SAST und bietet Entwicklungsorganisationen eine historische Ansicht der Scans. Die SAST-Integration in den CI/CD-Prozess ist ein wesentlicher Bestandteil der Erstellung von qualitativ hochwertigem, zuverlässigem und sicherem Code während der Integration und vor der endgültigen Auslieferung. Es erfüllt das Konzept der kontinuierlichen Softwaresicherung, bei der Softwaresicherungspraktiken in die Entwicklungsaktivitäten automatisiert werden, um eine schnelle Softwarebereitstellung und -bereitstellung zu gewährleisten.

Weißer Text auf marineblauem Hintergrund: So wählen Sie den richtigen sicheren Codierungsstandard aus und implementieren ihn mit der roten Schaltfläche darunter, die besagt, dass Sie das Whitepaper erhalten.

Von Kevin E. Greene

Kevin, Director of Security Solutions bei Parasoft, verfügt über umfangreiche Erfahrung und Fachkenntnisse in den Bereichen Software-Sicherheit, Cyber-Forschung und -Entwicklung sowie DevOps. Er nutzt sein Wissen, um sinnvolle Lösungen und Technologien zur Verbesserung der Software-Sicherheitspraktiken zu entwickeln.

Erhalten Sie die neuesten Nachrichten und Ressourcen zum Testen von Software sofort.