
Colete documentos VEX e atualize o VEX Hub
vexhub-crawler é um componente do VEX Hub que recupera automaticamente documentos VEX de repositórios de origem.
O crawler identifica repositórios de origem a partir de PURLs (URLs de Pacote) registrados e copia documentos VEX para o VEX Hub. Esse processo garante que o VEX Hub mantenha uma coleção atualizada de documentos VEX para diversos pacotes de software.
O diagrama a seguir ilustra o fluxo do processo de alto nível do VEX Hub Crawler, usando npm como exemplo:
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;
O VEX Hub Crawler mantém uma lista de PURLs para descobrir documentos VEX. O formato do arquivo de definição de PURL é o seguinte:
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
Ao especificar PURLs, os seguintes componentes são obrigatórios:
O version deve ser omitido. O namespace, qualifiers e subpath podem ser necessários para determinados ecossistemas, como oci. Para informações detalhadas sobre a composição de PURL, consulte a especificação do PURL.
A lista de PURLs pode ser atualizada por qualquer pessoa por meio de Pull Requests. Se os documentos VEX já estiverem armazenados no repositório de origem de um projeto de código aberto, pessoas que não sejam os mantenedores do projeto são bem-vindas para registrar o PURL no VEX Hub.
Atualmente, o crawler suporta os seguintes ecossistemas:
O método para identificar repositórios de origem varia de acordo com o ecossistema:
A API do registro npm será usada para resolver o repositório de origem. Cada pacote tem uma seção para definir o repositório.
Para o exemplo do React, seria assim:
$ curl -s https://registry.npmjs.org/react | jq .repository.url
"git+https://github.com/facebook/react.git"
O vexhub-crawler recuperará automaticamente os arquivos VEX armazenados em https://github.com/facebook/react.
Será feito um acesso HTTP para identificar o repositório a partir de go-import.
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>
A API do PyPI será usada para resolver o repositório.
curl -s https://pypi.org/pypi/<package-name>/json | jq .info.project_urls.Source
A API do crates.io será usada para resolver o repositório.
curl -s https://crates.io/api/v1/crates/<crate-name> | jq .crate.repository
Para pacotes Maven, o processo segue estas etapas para identificar o repositório de origem:
repository_url com base na especificação PURL. A URL padrão é https://repo.maven.apache.org/maven2.maven-metadata.xml usando o namespace e o nome do PURL. Por exemplo, para com.fasterxml.jackson.core:jackson-databind, a URL seria: https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/maven-metadata.xml.maven-metadata.xml,scm.url ou url no arquivo POM.Para imagens OCI, o repositório de origem é identificado examinando o label ou anotação org.opencontainers.image.source da tag latest. Os metadados são normalmente definidos durante o processo de build da imagem e fornecem uma forma padronizada de referenciar o repositório de código-fonte.
O processo é o seguinte:
repository_url e a tag :latest.latest.org.opencontainers.image.source nos seguintes locais:
Labels da configuração da imagemannotations do manifest da imagemExemplo de recuperação da URL de origem usando crane:
$ crane config ghcr.io/aquasecurity/trivy:latest | jq -r '.config.Labels["org.opencontainers.image.source"]'
https://github.com/aquasecurity/trivy
Uma vez identificado o repositório de origem (atualmente apenas repositórios git são suportados), o vexhub-crawler procura documentos VEX no diretório .vex/ na raiz do repositório.
O crawler considera como documentos VEX os arquivos que correspondem aos seguintes padrões:
O crawler realiza as seguintes validações:
O crawler copia os arquivos descobertos para o VEX Hub com seus nomes de arquivo originais. A estrutura de diretórios no VEX Hub é criada com base na Package URL (PURL), excluindo version, qualifiers e subpath.
O crawler adota um modelo de confiança baseado em documentos VEX armazenados em repositórios de origem. Conforme mencionado na seção Validação, ele filtra documentos VEX que declaram produtos diferentes do PURL original.
Por exemplo, se um PURL pkg:npm/malicious estiver registrado no VEX Hub e resolver para o repositório de origem github.com/org/malicious, qualquer documento VEX armazenado lá deve ter um ID de produto pkg:npm/malicious. Documentos VEX com IDs de produto diferentes, como pkg:npm/[email protected], serão ignorados.
Essa abordagem garante que apenas documentos VEX relevantes e confiáveis sejam incluídos no VEX Hub.
Atualmente, o VEX Hub Crawler usa APIs de registro para identificar repositórios de origem de pacotes. No entanto, essa abordagem apresenta riscos de segurança potenciais, pois as informações do repositório podem ser definidas livremente pelos mantenedores dos pacotes, tornando-as suscetíveis a adulteração.
Para enfrentar esse desafio, estamos considerando o uso de atestação de proveniência para uma resolução mais confiável do repositório de origem no futuro. A atestação de proveniência permite obter a URL real do repositório onde um pacote foi construído de forma confiável, possibilitando a verificação criptográfica da relação entre o código-fonte de um pacote e seus artefatos publicados.
Notavelmente, o npm já implementou proveniência em seu registro. Essa implementação torna possível recuperar as informações do repositório de origem diretamente do PURL usando dados de proveniência. Acreditamos que essa abordagem pode aumentar a confiabilidade do processo de resolução do repositório de origem para pacotes.