Naar de hoofdinhoud

SAST

fremforge draait OpenGrep op elke pull request en op de standaardbranch van elke repository. Het draait op de eigen scanners van fremforge, dus je hoeft geen workflowbestand toe te voegen. Een pull request krijgt de status fremforge/sast en een reactie. Bevindingen staan onder Beveiliging › Bevindingen › SAST (/<org>/_admin/security/findings/sast).

Talen

C, C++, C#, Go, Java, JavaScript en TypeScript, Kotlin, PHP, Python, Ruby, Rust, Scala, Swift en Bash.

Regels

Er zijn vier regelsets ingebouwd in de scannerimage. Tijdens een scan wordt er niets opgehaald:

  • GitLab sast-rules: alleen de regelmappen per taal, voor C#, Go, Java, JavaScript, Python en Scala. Ze vallen onder MIT, behalve de Go-regels, die zijn afgeleid van gosec en onder Apache-2.0 vallen;
  • de regels van 0xdea voor C en C++, MIT;
  • de eigen regels van fremforge, MIT, voor JavaScript en TypeScript, Bash, PHP, Ruby, Rust, Kotlin en Swift;
  • de eigen taint-regels van fremforge, MIT, voor Python, JavaScript en TypeScript, Java, C# en Go.

De GitLab-repository bevat ook inhoud onder andere licenties, die fremforge niet meelevert. De build van de image houdt een set op een toestaanlijst aan, de regelmappen per taal, en verwijdert de rest. Daarna controleert hij elk bestand dat hij heeft gehouden en faalt hij als een daarvan een andere licentie heeft dan MIT, Apache-2.0 of BSD.

Taint-regels

De taint-regels van fremforge volgen requestgegevens van het punt waar ze je code binnenkomen (een queryparameter, een formulierveld, een header, een cookie, een requestbody) tot het punt waar ze schade kunnen aanrichten, en melden het pad daartussen. Ze dekken SQL-injectie, command- en code-injectie, path traversal, server-side request forgery, cross-site scripting en onveilige deserialisatie in Python, JavaScript en TypeScript, Java, C# en Go. Ze kennen de requestobjecten van Flask, Django, FastAPI, aiohttp, Express, Koa, Hono, Next.js, Servlet, Spring, JAX-RS, ASP.NET Core, net/http, gin, echo en fiber. Een waarde die onderweg door een sanitizer gaat (een HTML-escape, een reductie tot een bestandsnaam, een gebonden SQL-parameter, een conversie naar een getal) wordt niet gemeld.

Wat ze volgen, en wat niet:

  • gegevens binnen een functie, en tussen functies in hetzelfde bestand;
  • geen gegevens die het ene bestand verlaten en in een ander terugkomen;
  • niet welke tak van een if wordt uitgevoerd, of onder welke sleutel van een map of index van een lijst een waarde staat: een waarde die wordt bewaakt door een controle die altijd slaagt, kan toch worden gemeld;
  • geen modellen van bibliotheken van derden buiten de sources, sinks en sanitizers die de regels noemen;
  • test- en specbestanden worden overgeslagen.

Elke bevinding bevat het pad van source naar sink. Ze staan aan voor de eigen organisaties van fremforge en uit voor andere zolang hun percentage vals-positieven wordt gemeten, en hun bevindingen worden getoond maar blokkeren het samenvoegen nooit, ongeacht hun ernst. Waar een taint-bevinding en een bevinding van een andere regel op dezelfde regel staan voor dezelfde zwakte (CWE), wordt alleen de taint-bevinding getoond. Zet ze aan of uit met de instelling taint_rules hieronder.

Je eigen regels

Een organisatie kan haar eigen OpenGrep-regels toevoegen. fremforge/sast draait ze samen met de ingebouwde regelsets op elke pull request en op de standaardbranch van elke repository, met dezelfde modus en blokkeerernst, en op een pull request blokkeert alleen wat die pull request toevoegt.

Voeg ze toe onder Beveiliging › Beleid › SAST-regels, via de API of met Terraform (hieronder). Elke regel is YAML met precies één regel onder rules:, en een testvoorbeeld: code die de regel moet vinden.

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(...)

Een regel moet hebben:

  • een id van 2 tot 63 kleine letters, cijfers en koppeltekens, uniek binnen de organisatie (de bevindingen ervan worden getoond als custom/<id>);
  • een message, een severity (ERROR, WARNING of INFO, getoond als Hoog, Gemiddeld en Laag) en 1 tot 5 languages: Bash, C, C++, C#, Dockerfile, generic, Go, HTML, Java, JavaScript, JSON, Kotlin, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript of YAML;
  • een patroon: pattern, patterns, pattern-either of pattern-regex, of mode: taint met pattern-sources en pattern-sinks.

Alleen sleutels voor patronen, metavariabelen en taint, en paths, fix, options en metadata zijn toegestaan, zodat een regel niet buiten zichzelf kan reiken. YAML-anchors en -aliassen worden geweigerd. Hoogstens 50 regels per organisatie, elk 16 KiB, met een testvoorbeeld van hoogstens 16 KiB.

Een opgeslagen regel staat op Wordt gecontroleerd tot de scanner hem heeft gedraaid met dezelfde opengrep, in dezelfde afgeschermde omgeving als je scans, op zijn eigen testvoorbeeld. Hij wordt Actief als hij wordt geparsed, iets vindt in het voorbeeld en binnen 30 seconden klaar is (5 seconden per bestand); anders wordt hij Afgewezen, met de reden. Alleen een actieve regel die niet is uitgezet, draait. Als je een regel of zijn voorbeeld wijzigt, wordt hij opnieuw gecontroleerd; tot dan draait hij niet. Je kunt een regel uitzetten zonder hem te verwijderen.

Bevindingen van je regels verschijnen samen met de ingebouwde, in de check van de pull request en onder Beveiliging › Bevindingen › SAST, gemarkeerd als Aangepast met de naam van de regel. Ze blokkeren zoals ingebouwde bevindingen: op basis van hun ernst ten opzichte van de blokkeerernst hieronder.

Regels worden opgeslagen in fremforge en vanuit fremforge gedraaid. De scanner haalt nooit regels op van een URL of een registry, en een regel controleren doet geen netwerkaanroep. De instelling custom_rules_url is buiten gebruik: ze wordt niet meer gelezen, en een andere waarde dan null of "" wordt geweigerd met custom-rules-url-removed.

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}

Opvragen vereist findings:read; wijzigingen vereisen policy:write. Een nieuwe of gewijzigde regel komt terug met status pending; het oordeel van de scanner zet die op valid of invalid, met status_code (bijvoorbeeld no-match of parse), status_detail (de eigen melding van opengrep, als die er is) en status_reason (een zin). Een regel die de API al kan weigeren voordat de scanner hem ziet, krijgt 400 met de reden (bijvoorbeeld one-rule of unknown-key); een id dat al bestaat geeft duplicate-id en de 51e regel limit-reached, beide 409. Elke wijziging staat in het auditlog.

Terraform en OpenTofu

Elke regel is een fremforge_sast_custom_rule (provider 0.5.0 en later). Een apply wacht op het oordeel van de scanner en faalt met de reden als de regel wordt afgewezen; zet wait_for_verdict = false om niet te wachten.

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 op fremforge_sast_settings is verouderd en wordt niet meer verzonden; haal het weg.

Instellingen

Onder Beveiliging › Bevindingen › SAST, of met GET en PUT /_app/api/v1/orgs/{org}/code-security/sast/settings (PUT vereist policy:write):

InstellingWaardenStandaard
SAST aan voor deze organisatieaan, uitaan
Blokkeerernstinfo, warning, error: bevindingen op of boven dit niveau laten fremforge/sast falenerror
Taint-regels (taint_rules)default, on, off. default is aan voor de eigen organisaties van fremforge en uit voor andere. Hun bevindingen blokkeren nooitdefault

Of een falende check het samenvoegen blokkeert, hangt ook af van de modus van de check onder Beveiliging › Prioriteren › Pull request-controles en van branchbeveiliging. Op een pull request blokkeren alleen bevindingen die de pull request introduceert: een bevinding die alleen naar een andere regel is verschoven, is niet nieuw.

Bevindingen

Bevindingen worden gerangschikt op betrouwbaarheid, dan op ernst, dan op de vraag of de scanner gegevens heeft gevolgd van een source zoals gebruikersinvoer tot de bevinding, en dan op leeftijd. Bevindingen in tests, voorbeelden, code van derden of gegenereerde code, en bevindingen van een regel die vaak wordt genegeerd, staan lager in de lijst; ze worden niet genegeerd. Negeer een bevinding met een reden, één voor één of in bulk, of met POST .../code-security/sast/findings/{id}/dismiss. De lijst staat ook op GET /_app/api/v1/orgs/{org}/code-security/sast/findings.

AI-fixes

Voor een korte lijst regels vraagt AI-fix het eigen AI-model van je organisatie om een pull request met een fix. Het staat standaard uit; zet het aan onder Beveiliging › Herstellen › AI-fix. Zie AI-fixes voor SAST-bevindingen.

Zie ook