SAST
fremforge führt OpenGrep bei jedem Pull Request und auf dem Standard-Branch jedes Repositorys aus. Es läuft auf den eigenen Scannern von fremforge, du musst also keine Workflow-Datei hinzufügen. Ein Pull Request erhält den Status fremforge/sast und einen Kommentar. Befunde stehen unter Sicherheit › Befunde › SAST (/<org>/_admin/security/findings/sast).
Sprachen
C, C++, C#, Go, Java, JavaScript und TypeScript, Kotlin, PHP, Python, Ruby, Rust, Scala, Swift und Bash.
Regeln
Vier Regelsätze sind fest in das Scanner-Image eingebaut. Während eines Scans wird nichts nachgeladen:
- GitLab sast-rules: nur die Regelordner pro Sprache, für C#, Go, Java, JavaScript, Python und Scala. Sie stehen unter MIT, außer den Go-Regeln, die von gosec abgeleitet sind und unter Apache-2.0 stehen;
- die Regeln von 0xdea für C und C++, MIT;
- die eigenen Regeln von fremforge, MIT, für JavaScript und TypeScript, Bash, PHP, Ruby, Rust, Kotlin und Swift;
- die eigenen Taint-Regeln von fremforge, MIT, für Python, JavaScript und TypeScript, Java, C# und Go.
Das GitLab-Repository enthält auch Inhalte unter anderen Lizenzen, die fremforge nicht ausliefert. Der Image-Build behält eine freigegebene Auswahl, die Regelordner pro Sprache, und löscht den Rest. Danach prüft er jede behaltene Datei und schlägt fehl, wenn eine davon eine andere Lizenz als MIT, Apache-2.0 oder BSD trägt.
Taint-Regeln
Die Taint-Regeln von fremforge verfolgen Anfragedaten von der Stelle, an der sie in deinen Code gelangen (ein Query-Parameter, ein Formularfeld, ein Header, ein Cookie, ein Request-Body), bis zu der Stelle, an der sie Schaden anrichten können, und melden den Pfad dazwischen. Sie decken SQL-Injection, Command- und Code-Injection, Path Traversal, Server-Side Request Forgery, Cross-Site-Scripting und unsichere Deserialisierung in Python, JavaScript und TypeScript, Java, C# und Go ab. Sie kennen die Request-Objekte von Flask, Django, FastAPI, aiohttp, Express, Koa, Hono, Next.js, Servlet, Spring, JAX-RS, ASP.NET Core, net/http, gin, echo und fiber. Ein Wert, der unterwegs durch einen Sanitizer läuft (ein HTML-Escape, eine Reduktion auf einen Dateinamen, ein gebundener SQL-Parameter, eine Umwandlung in eine Zahl), wird nicht gemeldet.
Was sie verfolgen und was nicht:
- Daten innerhalb einer Funktion und zwischen Funktionen in derselben Datei;
- keine Daten, die eine Datei verlassen und in einer anderen wieder auftauchen;
- nicht, welcher Zweig eines
ifausgeführt wird oder welcher Schlüssel einer Map oder welcher Index einer Liste einen Wert hält: Ein Wert, der durch eine immer erfüllte Prüfung abgesichert ist, kann trotzdem gemeldet werden; - keine Modelle von Drittanbieter-Bibliotheken über die Quellen, Senken und Sanitizer hinaus, die die Regeln benennen;
- Test- und Spec-Dateien werden ausgelassen.
Jeder Befund enthält den Pfad von der Quelle zur Senke. Sie sind für die eigenen Organisationen von fremforge eingeschaltet und für andere ausgeschaltet, solange ihre Fehlalarmquote gemessen wird, und ihre Befunde werden aufgeführt, blockieren aber nie einen Merge, unabhängig von ihrem Schweregrad. Liegen ein Taint-Befund und ein Befund einer anderen Regel auf derselben Zeile für dieselbe Schwäche (CWE), wird nur der Taint-Befund aufgeführt. Mit der Einstellung taint_rules unten schaltest du sie ein oder aus.
Deine eigenen Regeln
Eine Organisation kann eigene OpenGrep-Regeln hinzufügen. fremforge/sast führt sie zusammen mit den eingebauten Regelsätzen bei jedem Pull Request und auf dem Standard-Branch jedes Repositorys aus, mit demselben Modus und demselben Schweregrad für die Blockierung, und bei einem Pull Request blockiert nur, was er hinzufügt.
Füge sie unter Sicherheit › Richtlinien › SAST-Regeln hinzu, über die API oder mit Terraform (unten). Jede Regel ist YAML mit genau einer Regel unter rules: und einem Testbeispiel: Code, den die Regel finden muss.
rules:
- id: acme-no-eval
message: Do not pass data to eval(); use ast.literal_eval or a parser.
severity: ERROR
languages: [python]
pattern: eval(...)Eine Regel muss Folgendes haben:
- eine
idaus 2 bis 63 Kleinbuchstaben, Ziffern und Bindestrichen, eindeutig in der Organisation (ihre Befunde werden alscustom/<id>angezeigt); - eine
message, eineseverity(ERROR,WARNINGoderINFO, angezeigt als Hoch, Mittel und Niedrig) und 1 bis 5languages: Bash, C, C++, C#, Dockerfile, generic, Go, HTML, Java, JavaScript, JSON, Kotlin, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript oder YAML; - ein Muster:
pattern,patterns,pattern-eitheroderpattern-regex, odermode: taintmitpattern-sourcesundpattern-sinks.
Erlaubt sind nur Schlüssel für Muster, Metavariablen, Taint, paths, fix, options und metadata, sodass eine Regel nicht über sich selbst hinausgreifen kann. YAML-Anker und -Aliase werden abgewiesen. Höchstens 50 Regeln pro Organisation, je 16 KiB, mit einem Testbeispiel von höchstens 16 KiB.
Eine gespeicherte Regel steht auf Wird geprüft, bis der Scanner sie mit demselben opengrep, in derselben abgeschotteten Umgebung wie deine Scans, auf ihrem eigenen Testbeispiel ausgeführt hat. Sie wird Aktiv, wenn sie sich parsen lässt, im Beispiel etwas findet und innerhalb von 30 Sekunden fertig wird (5 Sekunden pro Datei); andernfalls wird sie Abgelehnt, mit Begründung. Nur eine aktive Regel, die nicht ausgeschaltet ist, wird ausgeführt. Änderst du eine Regel oder ihr Beispiel, wird sie erneut geprüft; bis dahin läuft sie nicht. Du kannst eine Regel ausschalten, ohne sie zu löschen.
Befunde deiner Regeln erscheinen zusammen mit den eingebauten, in der Pull-Request-Prüfung und unter Sicherheit › Befunde › SAST, gekennzeichnet als Benutzerdefiniert mit dem Namen der Regel. Sie blockieren wie eingebaute Befunde: nach ihrem Schweregrad im Vergleich zum unten eingestellten Schweregrad für die Blockierung.
Regeln werden in fremforge gespeichert und von dort ausgeführt. Der Scanner lädt nie Regeln von einer URL oder aus einer Registry, und die Prüfung einer Regel macht keinen Netzwerkaufruf. Die Einstellung custom_rules_url ist außer Betrieb: Sie wird nicht mehr gelesen, und ein anderer Wert als null oder "" wird mit custom-rules-url-removed abgewiesen.
API
GET /_app/api/v1/orgs/{org}/code-security/sast/custom-rules
GET /_app/api/v1/orgs/{org}/code-security/sast/custom-rules/{id}
POST /_app/api/v1/orgs/{org}/code-security/sast/custom-rules { "name": "No eval", "source": "<yaml>", "sample": "<code>", "enabled": true }
PUT /_app/api/v1/orgs/{org}/code-security/sast/custom-rules/{id}
DELETE /_app/api/v1/orgs/{org}/code-security/sast/custom-rules/{id}Zum Auflisten brauchst du findings:read, für Änderungen policy:write. Eine neue oder geänderte Regel kommt mit status pending zurück; das Urteil des Scanners setzt ihn auf valid oder invalid, mit status_code (zum Beispiel no-match oder parse), status_detail (die eigene Meldung von opengrep, sofern es eine gibt) und status_reason (ein Satz). Eine Regel, die die API schon abweisen kann, bevor der Scanner sie sieht, wird mit 400 und der Begründung beantwortet (zum Beispiel one-rule oder unknown-key); eine bereits vergebene ID ergibt duplicate-id und die 51. Regel limit-reached, beide 409. Jede Änderung steht im Audit-Log.
Terraform und OpenTofu
Jede Regel ist eine fremforge_sast_custom_rule (Provider 0.5.0 und neuer). Ein Apply wartet auf das Urteil des Scanners und schlägt mit der Begründung fehl, wenn die Regel abgelehnt wird; setze wait_for_verdict = false, um das Warten zu überspringen.
resource "fremforge_sast_custom_rule" "no_eval" {
org = "acme"
name = "No eval"
source = file("sast/no-eval.yaml")
sample = file("sast/no-eval.sample.py")
}custom_rules_url auf fremforge_sast_settings ist veraltet und wird nicht mehr gesendet; entferne es.
Einstellungen
Unter Sicherheit › Befunde › SAST oder mit GET und PUT /_app/api/v1/orgs/{org}/code-security/sast/settings (PUT braucht policy:write):
| Einstellung | Werte | Standard |
|---|---|---|
| SAST für diese Organisation aktiviert | an, aus | an |
| PR-Merge blockieren ab Schweregrad | info, warning, error: Befunde auf oder über dieser Stufe lassen fremforge/sast fehlschlagen | error |
Taint-Regeln (taint_rules) | default, on, off. default ist für die eigenen Organisationen von fremforge eingeschaltet und für andere ausgeschaltet. Ihre Befunde blockieren nie | default |
Ob eine fehlschlagende Prüfung einen Merge blockiert, hängt außerdem vom Modus der Prüfung unter Sicherheit › Priorisieren › Pull-Request-Prüfungen und vom Branch-Schutz ab. Bei einem Pull Request blockieren nur Befunde, die der Pull Request einführt: Ein Befund, der nur in eine andere Zeile gewandert ist, ist nicht neu.
Befunde
Befunde werden nach Konfidenz sortiert, dann nach Schweregrad, dann danach, ob der Scanner Daten von einer Quelle wie einer Benutzereingabe bis zum Befund verfolgt hat, dann nach Alter. Befunde in Tests, Beispielen, Drittanbieter- oder generiertem Code sowie Befunde einer Regel, die oft verworfen wird, stehen weiter unten; sie werden nicht verworfen. Verwirf einen Befund mit Begründung, einzeln oder gesammelt, oder mit POST .../code-security/sast/findings/{id}/dismiss. Die Liste gibt es auch unter GET /_app/api/v1/orgs/{org}/code-security/sast/findings.
KI-Korrekturen
Für eine kurze Liste von Regeln fragt die KI-Korrektur das eigene KI-Modell deiner Organisation nach einem Korrektur-Pull-Request. Sie ist standardmäßig aus; schalte sie unter Sicherheit › Beheben › KI-Korrektur ein. Siehe KI-Korrekturen für SAST-Befunde.