
Collect VEX documents and update VEX Hub
vexhub-crawler ist eine Komponente des VEX Hub, die automatisch VEX-Dokumente aus Quell-Repositorys abruft.
Der Crawler ermittelt Quell-Repositorys anhand registrierter PURLs (Package URLs) und kopiert VEX-Dokumente in den VEX Hub. Dieser Prozess stellt sicher, dass der VEX Hub eine aktuelle Sammlung von VEX-Dokumenten für verschiedene Softwarepakete pflegt.
Das folgende Diagramm veranschaulicht den allgemeinen Prozessablauf des VEX Hub Crawlers am Beispiel von npm:
flowchart TD
Dev[Developer] -->|Register package| PL[Package List]
PL -->|Provide packages for crawling| Crawler
Crawler -->|Identify repository URL| Registry[Package Registry]
Crawler -->|Retrieve VEX documents| Src
Crawler -->|Validate and update VEX documents| Hub
subgraph crawler [VEX Hub Crawler]
Crawler
PL
end
subgraph bottom [ ]
direction LR
Registry
Src
Hub[VEX Hub]
subgraph Src[Source Repository]
direction TB
VEX[VEX documents<br>under .vex/ directory]
end
end
classDef dev fill:#b3d9ff,stroke:#2a4d69,stroke-width:1px,color:#2a4d69;
classDef vexHub fill:#ffd9e6,stroke:#4b3832,stroke-width:1px,color:#4b3832;
classDef crawler fill:#c2f0c2,stroke:#1e4d2b,stroke-width:1px,color:#1e4d2b;
classDef npmReg fill:#ffe6cc,stroke:#5e3023,stroke-width:1px,color:#5e3023;
classDef sourceRepo fill:#e6ccff,stroke:#3b2e58,stroke-width:1px,color:#3b2e58;
classDef pkgList fill:#ccf2ff,stroke:#1c4e5a,stroke-width:1px,color:#1c4e5a;
classDef invisible fill:none,stroke:none;
class Dev dev;
class Hub vexHub;
class crawler crawler;
class Registry npmReg;
class Src,VEX sourceRepo;
class PL pkgList;
class bottom invisible;
Der VEX Hub Crawler pflegt eine Liste von PURLs zum Auffinden von VEX-Dokumenten. Das Format der PURL-Definitionsdatei ist wie folgt:
pkg:
npm:
- namespace: "@angular"
name: animations
golang:
- name: github.com/aquasecurity/trivy
pypi:
- name: django
maven:
- namespace: org.junit.jupiter
name: junit-jupiter-api
oci:
- name: trivy
qualifiers:
- key: repository_url
value: index.docker.io/aquasec/trivy
- name: trivy
qualifiers:
- key: repository_url
value: ghcr.io/aquasecurity/trivy
Bei der Angabe von PURLs sind die folgenden Komponenten erforderlich:
Die version muss weggelassen werden.
namespace, qualifiers und subpath können für bestimmte Ökosysteme wie oci erforderlich sein.
Detaillierte Informationen zum Aufbau von PURLs finden Sie in der PURL-Spezifikation.
Die Liste der PURLs kann von jedem über Pull Requests aktualisiert werden. Wenn VEX-Dokumente bereits im Quell-Repository eines Open-Source-Projekts gespeichert sind, sind auch Personen, die nicht zu den Maintainern des Projekts gehören, willkommen, die PURL im VEX Hub zu registrieren.
Derzeit unterstützt der Crawler die folgenden Ökosysteme:
Die Methode zur Identifizierung von Quell-Repositorys variiert je nach Ökosystem:
Die npm-Registry-API wird verwendet, um das Quell-Repository aufzulösen. Jedes Paket besitzt einen Abschnitt, um das Repository zu definieren.
Am Beispiel von React sieht das wie folgt aus:
$ curl -s https://registry.npmjs.org/react | jq .repository.url
"git+https://github.com/facebook/react.git"
vexhub-crawler ruft automatisch die VEX-Dateien ab, die unter https://github.com/facebook/react gespeichert sind.
Es wird ein HTTP-Zugriff durchgeführt, um das Repository anhand von go-import zu identifizieren.
curl -s "https://k8s.io/client-go?go-get=1"
<html><head>
<meta name="go-import"
content="k8s.io/client-go
git https://github.com/kubernetes/client-go">
<meta name="go-source"
content="k8s.io/client-go
https://github.com/kubernetes/client-go
https://github.com/kubernetes/client-go/tree/master{/dir}
https://github.com/kubernetes/client-go/blob/master{/dir}/{file}#L{line}">
</head></html>
Die PyPI-API wird verwendet, um das Repository aufzulösen.
curl -s https://pypi.org/pypi/<package-name>/json | jq .info.project_urls.Source
Die crates.io-API wird verwendet, um das Repository aufzulösen.
curl -s https://crates.io/api/v1/crates/<crate-name> | jq .crate.repository
Für Maven-Pakete werden die folgenden Schritte durchgeführt, um das Quell-Repository zu identifizieren:
repository_url gemäß der PURL-Spezifikation ermittelt. Die Standard-URL ist https://repo.maven.apache.org/maven2.maven-metadata.xml unter Verwendung von Namespace und Name aus der PURL konstruiert. Für com.fasterxml.jackson.core:jackson-databind wäre die URL beispielsweise: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/maven-metadata.xml.maven-metadata.xml extrahiert.scm.url oder url in der POM-Datei identifiziert.Bei OCI-Images wird das Quell-Repository durch Prüfung des Labels bzw. der Annotation org.opencontainers.image.source des latest-Tags identifiziert.
Die Metadaten werden in der Regel während des Image-Build-Prozesses gesetzt und bieten eine standardisierte Möglichkeit, auf das Quellcode-Repository zu verweisen.
Der Prozess ist wie folgt:
repository_url und der Tag :latest angehängt werden.latest-Tag werden abgerufen.org.opencontainers.image.source wird an den folgenden Stellen gesucht:
Labels der Image-Konfigurationannotations des Image-ManifestsBeispiel für das Abrufen der Quell-URL mit crane:
$ crane config ghcr.io/aquasecurity/trivy:latest | jq -r '.config.Labels["org.opencontainers.image.source"]'
https://github.com/aquasecurity/trivy
Sobald das Quell-Repository identifiziert ist (derzeit werden nur Git-Repositorys unterstützt), sucht vexhub-crawler im .vex/-Verzeichnis im Stammverzeichnis des Repositorys nach VEX-Dokumenten.
Der Crawler betrachtet Dateien, die den folgenden Mustern entsprechen, als VEX-Dokumente:
Der Crawler führt die folgenden Validierungen durch:
Der Crawler kopiert die gefundenen Dateien mit ihren ursprünglichen Dateinamen in den VEX Hub. Die Verzeichnisstruktur im VEX Hub wird auf Grundlage der Package URL (PURL) erstellt, ohne Version, Qualifier und Subpath.
Der Crawler verwendet ein Vertrauensmodell, das auf in Quell-Repositorys gespeicherten VEX-Dokumenten basiert. Wie im Abschnitt Validierung erwähnt, filtert er VEX-Dokumente heraus, die andere Produkte als die ursprüngliche PURL deklarieren.
Wenn beispielsweise eine PURL pkg:npm/malicious im VEX Hub registriert ist und auf das Quell-Repository github.com/org/malicious aufgelöst wird, müssen alle dort gespeicherten VEX-Dokumente eine Produkt-ID von pkg:npm/malicious aufweisen.
VEX-Dokumente mit anderen Produkt-IDs, wie pkg:npm/[email protected], werden ignoriert.
Dieser Ansatz stellt sicher, dass nur relevante und vertrauenswürdige VEX-Dokumente in den VEX Hub aufgenommen werden.
Derzeit verwendet der VEX Hub Crawler Registry-APIs, um Paket-Quell-Repositorys zu identifizieren. Dieser Ansatz birgt jedoch potenzielle Sicherheitsrisiken, da Repository-Informationen von Paket-Maintainern frei festgelegt werden können und dadurch anfällig für Manipulationen sind.
Um dieser Herausforderung zu begegnen, erwägen wir, in Zukunft Provenanz-Attestierungen (provenance attestation) für eine zuverlässigere Auflösung von Quell-Repositorys zu verwenden. Provenanz-Attestierungen ermöglichen es, die tatsächliche Repository-URL, in der ein Paket erstellt wurde, auf vertrauenswürdige Weise zu erhalten und die Beziehung zwischen dem Quellcode eines Pakets und seinen veröffentlichten Artefakten kryptografisch zu verifizieren.
Bemerkenswerterweise hat npm Provenanz bereits in seiner Registry implementiert. Diese Implementierung ermöglicht es, die Quell-Repository-Informationen mithilfe von Provenanzdaten direkt aus der PURL abzurufen. Wir glauben, dass dieser Ansatz die Vertrauenswürdigkeit des Prozesses zur Auflösung von Quell-Repositorys für Pakete verbessern kann.