Konfiguration, Findings-Triage und False-Positive-Handling
Statische Codeanalyse und Abhaengigkeitspruefung gehoeren zu den Security-Funktionen, die GitLab direkt eingebaut mitliefert und die sich mit wenigen Zeilen in eine bestehende .gitlab-ci.yml einbinden lassen. Der eigentliche Aufwand beginnt aber erst danach: Ergebnisse muessen bewertet, echte Schwachstellen priorisiert und Falschmeldungen sauber unterdrueckt werden, ohne dass das Security-Rauschen die Entwicklerakzeptanz untergraebt. Dieser Artikel zeigt die Integration von SAST und Dependency Scanning in eine bestehende PHP- oder Node-Pipeline sowie den praktischen Umgang mit den gemeldeten Findings.
Inhaltsverzeichnis
- 1. Was SAST und Dependency Scanning jeweils leisten
- 2. SAST in eine bestehende Pipeline einbinden
- 3. Dependency Scanning fuer PHP und Node einbinden
- 4. Wie GitLab Findings darstellt und priorisiert
- 5. Vom Finding zum behobenen Issue: Ein praktischer Workflow
- 6. Umgang mit False Positives
- 7. Schwellenwerte und Pipeline-Verhalten bei Findings steuern
- 8. Auswirkungen auf Pipeline-Laufzeit und Ressourcenverbrauch
- 9. Best Practices fuer den nachhaltigen Betrieb
- 10. Zusammenfassung
- 11. FAQ
1. Was SAST und Dependency Scanning jeweils leisten
Static Application Security Testing, kurz SAST, analysiert den eigenen Quellcode ohne ihn auszufuehren und sucht nach bekannten unsicheren Mustern wie unsanitisierten SQL-Queries, unsicherer Deserialisierung oder hartcodierten Zugangsdaten. Dependency Scanning dagegen betrachtet nicht den eigenen Code, sondern die Liste der eingebundenen Drittanbieter-Pakete, etwa aus composer.lock oder package-lock.json, und gleicht sie mit einer Datenbank bekannter Schwachstellen ab. Beide Analysen ergaenzen sich, weil ein Grossteil realer Sicherheitsluecken heute in Abhaengigkeiten steckt, nicht im selbst geschriebenen Code.
GitLab liefert fuer beide Analysearten fertige CI/CD-Templates mit, die als include:template eingebunden werden und automatisch die passenden Analyzer fuer die im Repository erkannten Sprachen auswaehlen. Fuer eine PHP-Codebasis kommt dabei zum Beispiel semgrep als SAST-Analyzer und gemnasium-php als Dependency-Scanner zum Einsatz, fuer Node.js entsprechend semgrep und gemnasium-nodejs. Diese automatische Erkennung nimmt viel manuelle Konfigurationsarbeit ab, funktioniert aber nur zuverlaessig, wenn die Projektstruktur den ueblichen Konventionen der jeweiligen Sprache folgt.
2. SAST in eine bestehende Pipeline einbinden
Die Grundintegration ist bewusst minimal gehalten: Ein include:template Eintrag fuer Security/SAST.gitlab-ci.yml reicht aus, um die passenden Analyzer-Jobs automatisch der Pipeline hinzuzufuegen. GitLab fuehrt intern eine Erkennung der im Repository vorhandenen Sprachen durch und aktiviert nur die tatsaechlich relevanten Analyzer, sodass in einem reinen PHP-Projekt kein unnoetiger Java- oder Go-Scan mitlaeuft. Die Ergebnisse werden am Ende als SAST-Report-Artifact abgelegt, das GitLab automatisch im Merge-Request-Widget als Security-Findings-Liste anzeigt.
Fuer bestehende, bereits gewachsene Pipelines ist wichtig, dass der SAST-Job standardmaessig in der Stage test laeuft. Ist diese Stage in der eigenen .gitlab-ci.yml nicht vorhanden oder anders benannt, muss entweder die eigene Stage-Liste um test ergaenzt oder der SAST-Job explizit einer vorhandenen Stage zugewiesen werden. Ein haeufiger Stolperstein ist zudem, dass SAST bei sehr grossen Monorepos deutlich laenger laeuft als der Rest der Pipeline, weshalb sich eine eigene, parallele Stage fuer Security-Jobs oft lohnt, um die Gesamtlaufzeit nicht unnoetig zu verlaengern.
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy
include:
- template: 'Security/SAST.gitlab-ci.yml'
semgrep-sast:
stage: security
3. Dependency Scanning fuer PHP und Node einbinden
Dependency Scanning wird analog ueber include:template mit Security/Dependency-Scanning.gitlab-ci.yml eingebunden und erkennt Manifestdateien wie composer.lock, package-lock.json oder yarn.lock automatisch. Fuer PHP-Projekte muss composer install vor dem Scan-Job gelaufen sein, damit die vollstaendige Abhaengigkeitsstruktur inklusive transitiver Pakete verfuegbar ist, andernfalls analysiert der Scanner nur eine unvollstaendige Teilmenge. Bei Node-Projekten gilt entsprechend, dass npm ci oder yarn install vorher ausgefuehrt sein sollte, damit die Lockfile-Version mit der tatsaechlich installierten Version uebereinstimmt.
Ein wichtiger praktischer Unterschied zu SAST ist, dass Dependency Scanning auf eine regelmaessig aktualisierte, extern gepflegte Vulnerability-Datenbank angewiesen ist. Neue Schwachstellen in bereits eingebundenen Paketen koennen daher auch dann auftauchen, wenn sich am eigenen Code seit Wochen nichts geaendert hat, einfach weil eine neue CVE fuer eine bestehende Abhaengigkeit veroeffentlicht wurde. Genau das macht die Kombination mit einer Scheduled Pipeline sinnvoll, die regelmaessig unabhaengig von Code-Aenderungen nach neuen Findings sucht.
# .gitlab-ci.yml
include:
- template: 'Security/Dependency-Scanning.gitlab-ci.yml'
gemnasium-php-dependency_scanning:
stage: security
before_script:
- composer install --no-dev --prefer-dist
4. Wie GitLab Findings darstellt und priorisiert
Jedes gemeldete Finding erhaelt automatisch eine Schweregradeinstufung von Info ueber Low, Medium und High bis Critical, basierend auf dem CVSS-Score der zugrunde liegenden Schwachstelle oder der Regelklassifikation des SAST-Analyzers. Im Merge-Request-Widget erscheinen neue Findings direkt bei der betroffenen Codezeile beziehungsweise beim betroffenen Paket, sodass Reviewer sie sehen, ohne einen separaten Report oeffnen zu muessen. Das Security-Dashboard auf Projekt- und Gruppenebene aggregiert zusaetzlich alle Findings ueber die Zeit und macht Trends sichtbar, etwa ob die Zahl offener High-Severity-Findings steigt oder faellt.
Fuer die Priorisierung im Alltag hat sich bewaehrt, sich zunaechst ausschliesslich auf Critical- und High-Findings zu konzentrieren und Medium- sowie Low-Findings in regelmaessigen, aber weniger haeufigen Reviews zu behandeln, etwa monatlich statt bei jedem Merge Request. Ohne diese Priorisierung droht ein Team schnell in einer Flut von Findings unterzugehen, von denen viele geringe reale Auswirkung haben, waehrend die tatsaechlich kritischen Funde in der Masse untergehen.
5. Vom Finding zum behobenen Issue: Ein praktischer Workflow
Ein bewaehrter Workflow beginnt damit, jedes Critical- oder High-Finding direkt aus dem Security-Dashboard heraus in ein GitLab-Issue umzuwandeln, was GitLab mit einem einzigen Klick erlaubt und automatisch alle relevanten Metadaten wie betroffene Datei, Zeilennummer und CVE-Referenz mitgibt. Dieses Issue durchlaeuft dann denselben Priorisierungs- und Zuweisungsprozess wie jeder andere Bug, statt in einer separaten, oft vernachlaessigten Security-Liste zu verschwinden.
Bei Dependency-Scanning-Findings ist die Loesung haeufig ein simples Versions-Update der betroffenen Abhaengigkeit, was sich mit composer update paketname oder npm update paketname umsetzen laesst, gefolgt von einem erneuten Pipeline-Lauf zur Bestaetigung. Bei SAST-Findings im eigenen Code ist dagegen meist eine echte Code-Aenderung noetig, etwa der Wechsel von einer unsicheren String-Konkatenation in einer SQL-Query zu einem parametrisierten Statement, was in der Regel einen eigenen Merge Request mit Review verdient statt eines schnellen Patches ohne Zweitpruefung.
6. Umgang mit False Positives
Kein automatisierter Scanner ist perfekt, und sowohl SAST als auch Dependency Scanning erzeugen gelegentlich Findings, die bei genauerer Pruefung keine echte Schwachstelle darstellen. Ein klassisches Beispiel ist ein SAST-Finding fuer eine vermeintlich unsichere Funktion, die im konkreten Kontext bereits durch eine vorgelagerte Validierung abgesichert ist, oder ein Dependency-Finding fuer ein Paket, dessen verwundbarer Codepfad im eigenen Projekt gar nicht genutzt wird. Solche Faelle direkt als erledigt zu ignorieren, ohne sie zu dokumentieren, fuehrt dazu, dass derselbe Scanner beim naechsten Lauf erneut denselben Alarm ausloest.
GitLab bietet dafuer im Security-Dashboard die Moeglichkeit, ein Finding explizit als False Positive zu markieren, inklusive eines Pflichtfeldes fuer die Begruendung. Diese Markierung wird dauerhaft gespeichert und verhindert, dass dasselbe Finding bei zukuenftigen Scans erneut als offen auftaucht, solange sich der zugrunde liegende Code oder die Abhaengigkeitsversion nicht aendert. Wichtig ist, diese Begruendungen tatsaechlich sorgfaeltig zu dokumentieren, da eine spaetere Ueberpruefung durch einen Security-Auditor sonst nicht nachvollziehen kann, warum ein Finding als unkritisch eingestuft wurde.
# .gitlab-ci.yml: Ausschluss eines Pfads von SAST
variables:
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp, vendor/legacy-lib"
7. Schwellenwerte und Pipeline-Verhalten bei Findings steuern
Standardmaessig blockiert ein Security-Finding die Pipeline nicht automatisch, sondern erscheint lediglich als Information im Merge-Request-Widget, damit Entwickler nicht durch jeden einzelnen Low-Finding an einem Merge gehindert werden. Fuer strengere Anforderungen laesst sich ueber Security-Policies auf Gruppen- oder Projektebene ein sogenanntes Scan Result Policy definieren, das zum Beispiel jeden Merge mit einem ungeloesten Critical-Finding automatisch blockiert, bis entweder eine Behebung erfolgt oder eine autorisierte Ausnahme genehmigt wurde.
Diese Policies lassen sich granular konfigurieren, etwa nur fuer bestimmte Branches wie main greifen zu lassen, waehrend Feature-Branches weiterhin frei entwickelt werden koennen. In regulierten Umgebungen, in denen Compliance-Vorgaben eine dokumentierte Freigabe fuer jede bekannte Schwachstelle verlangen, ist eine solche Policy oft unverzichtbar, waehrend kleinere Teams haeufig mit der reinen Sichtbarkeit im Merge-Request-Widget gut zurechtkommen, ohne harte Blockaden einzufuehren.
8. Auswirkungen auf Pipeline-Laufzeit und Ressourcenverbrauch
SAST- und Dependency-Scanning-Jobs benoetigen eigene, teils recht speicherintensive Analyzer-Container, was die Gesamtlaufzeit einer Pipeline spuerbar verlaengern kann, insbesondere bei grossen Codebasen. In der Praxis hat es sich bewaehrt, diese Jobs in einer eigenen, parallel zu Test-Jobs laufenden Stage zu platzieren, statt sie sequentiell nach den funktionalen Tests einzureihen, sodass sich Test- und Security-Laufzeit ueberlappen statt zu addieren.
Fuer sehr grosse Repositories bietet sich zudem an, Dependency Scanning nicht bei jedem Push, sondern nur bei Merge Requests gegen den main-Branch sowie zusaetzlich per Scheduled Pipeline nachts laufen zu lassen, wie im vorangegangenen Artikel zu Scheduled Pipelines beschrieben. Das reduziert den CI-Minuten-Verbrauch spuerbar, ohne die Sicherheit zu gefaehrden, da neue Schwachstellen in bestehenden Abhaengigkeiten ohnehin unabhaengig vom Zeitpunkt eines Commits erkannt werden muessen.
9. Best Practices fuer den nachhaltigen Betrieb
Ein nachhaltiger Security-Scanning-Betrieb braucht klare Verantwortlichkeiten: Wer sichtet neue Findings, wer entscheidet ueber False-Positive-Markierungen und wer eskaliert Critical-Findings ausserhalb des normalen Sprint-Rhythmus. Ohne diese Klarheit verwaisen Findings im Dashboard und die anfaengliche Investition in die Integration verpufft, weil niemand die gemeldeten Probleme tatsaechlich abarbeitet.
Ebenso wichtig ist ein regelmaessiger Blick auf die False-Positive-Rate: Steigt sie ueber die Zeit deutlich an, deutet das oft auf eine zu aggressive Analyzer-Konfiguration hin, die durch gezieltes Anpassen der SAST_EXCLUDED_PATHS oder durch Deaktivieren einzelner, projektspezifisch irrelevanter Regeln reduziert werden kann. Die folgende Tabelle vergleicht die wichtigsten Eigenschaften von SAST und Dependency Scanning, um beide Analysearten klar voneinander abzugrenzen.
| Merkmal | SAST | Dependency Scanning |
|---|---|---|
| Analysiert | Eigenen Quellcode | Eingebundene Drittanbieter-Pakete |
| Datenquelle | Statische Analyzer-Regeln | Externe Vulnerability-Datenbank |
| Aendert sich ohne Code-Aenderung | Nein | Ja, bei neuer CVE fuer bestehendes Paket |
| Typische Behebung | Code-Aenderung mit Review | Versions-Update der Abhaengigkeit |
| Empfohlener Rhythmus | Bei jedem Merge Request | Merge Request plus naechtliche Scheduled Pipeline |
Mironsoft
CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung
Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?
Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.
Pipeline-Review
Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.
Zero-Downtime-Deployment
Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.
CI/CD-Automatisierung
Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.
10. Zusammenfassung
GitLab SAST und Dependency Scanning: Das Wichtigste auf einen Blick
Zwei Analysearten
SAST prueft eigenen Code, Dependency Scanning prueft Drittanbieter-Pakete gegen eine Vulnerability-Datenbank.
Minimale Integration
Ein include:template Eintrag reicht aus, GitLab erkennt Sprachen und passende Analyzer automatisch.
Findings triagieren
Critical und High priorisiert in Issues umwandeln, Medium und Low in regelmaessigen Reviews behandeln.
False Positives dokumentieren
Explizite Markierung im Security-Dashboard mit Begruendung statt stillem Ignorieren.