Skip to main content

O que você pode fazer com um SBOM enriquecido? Guia rápido do parlay

Escrito por
blog feature parlay announcement

7 de junho de 2023

0 minutos de leitura

Acabamos de lançar o parlay, uma nova ferramenta de código aberto que pode enriquecer SBOMs com informações adicionais. Saiba mais na publicação de anúncio. Nela, mencionamos brevemente por que isso é importante para tomar decisões com base em dados de SBOMs, mas achamos que alguns exemplos rápidos também poderiam ser interessantes.

O parlay pode adicionar muitas informações a um SBOM, e podemos usá-las para criar políticas mais poderosas. Embora a quantidade de linhas de JSON não seja um indicador perfeito, neste exemplo específico o SBOM cresceu mais de 400% — o que abre espaço para muitos casos de uso.

$ snyk sbom --format cyclonedx1.4+json | jq | wc -l
    262
$ snyk sbom --format cyclonedx1.4+json | parlay e enrich - | jq | wc -l
    1169

Políticas de licença

Um SBOM com apenas os elementos mínimos não contém informações sobre as licenças aplicáveis aos pacotes incluídos. Vamos usar o Parlay e os dados do Ecosyste.ms para adicionar essas informações.

snyk sbom --format cyclonedx1.4+json | parlay e enrich -

Agora que temos um SBOM mais completo, podemos criar políticas mais poderosas. Neste exemplo, vamos usar o Open Policy Agent e sua poderosa linguagem de programação Rego. Aqui, criamos duas listas de políticas: uma para bloquear e outra para emitir avisos.

package main

name = input.metadata.component.name

licenses_to_deny = [
  "LGPL",
]

licenses_to_warn = [
  "MIT"
]

deny[msg] {
  component := input.components[_]
  expression := component.licenses[_].expression
  startswith(expression, licenses_to_deny[_])
  msg := sprintf("%s is using %s which is licensed with an %s license", [name, component.name, expression])
}

warn[msg] {
    component := input.components[_]
    expression := component.licenses[_].expression
    startswith(expression, licenses_to_warn[_])
    msg := sprintf("%s is using %s which is licensed with an %s license", [name, component.name, expression])
}

Vamos continuar celebrando os pipes do Unix e usar o Conftest para aplicar essa política ao SBOM enriquecido.

snyk sbom --format cyclonedx1.4+json | parlay e enrich - | conftest test -

No projeto de exemplo, isso gerou uma série de avisos sobre determinados pacotes que usam as licenças indicadas.

WARN - - main - snykit is using diff-lcs which is licensed with an MIT license
WARN - - main - snykit is using mustermann which is licensed with an MIT license
WARN - - main - snykit is using nio4r which is licensed with an MIT license
WARN - - main - snykit is using puma-metrics which is licensed with an MIT license
WARN - - main - snykit is using rack which is licensed with an MIT license
WARN - - main - snykit is using rack-protection which is licensed with an MIT license
WARN - - main - snykit is using rack-test which is licensed with an MIT license
WARN - - main - snykit is using rake which is licensed with an MIT license
WARN - - main - snykit is using rspec which is licensed with an MIT license
WARN - - main - snykit is using rspec-core which is licensed with an MIT license
WARN - - main - snykit is using rspec-expectations which is licensed with an MIT license
WARN - - main - snykit is using rspec-mocks which is licensed with an MIT license
WARN - - main - snykit is using rspec-support which is licensed with an MIT license
WARN - - main - snykit is using sinatra which is licensed with an MIT license
WARN - - main - snykit is using tilt which is licensed with an MIT license

16 tests, 1 passed, 15 warnings, 0 failures, 0 exceptions

Políticas de vulnerabilidade

Vamos tentar algo um pouco mais complexo: criar uma política para sinalizar vulnerabilidades com pontuação CVSS acima de um determinado limite em dependências diretas. Este é um bom exemplo de quando você precisa de dados sobre pacotes, dependências e vulnerabilidades.

deny[msg] {
  vulnerability := input.vulnerabilities[_]
  rating := vulnerability.ratings[_]
  rating.source.name == "Snyk"
  rating.score > max_cvss_score
  component := input.components[_]
  bom_ref = vulnerability["bom-ref"]
  component["bom-ref"] == bom_ref

  root = input.metadata.component["bom-ref"]

  dependency := input.dependencies[_]
  dependency.ref == root

  direct := dependency.dependsOn[_]
  direct == bom_ref

  msg := sprintf("%s version %s has a vulnerability with a CVSS score of %s", [component.name, component.version, round(rating.score)])
}

round(n) = f {
  f := sprintf("%.2f", [n])
  contains(f, ".") # Ensure that it was a float
}

round(n) = f {
  not contains(sprintf("%.2f", [n]), ".") # Test if it wasn't a float
  f := sprintf("%v.00", [n]) # Fudge the decimals for integer values
}

Em seguida, podemos gerar ou obter nosso SBOM, enriquecê-lo com os dados de vulnerabilidade da Snyk e aplicar nossa política usando o Conftest.

snyk sbom --format cyclonedx1.4+json | parlay s enrich - | conftest test -
FAIL - - main - puma version 4.2.1 has a vulnerability with a CVSS score of 9.10

3 tests, 2 passed, 0 warnings, 1 failure, 0 exceptions

Aqui, vemos um relatório sobre uma vulnerabilidade que corresponde aos nossos critérios.

Lembre-se: este é apenas um exemplo. A linguagem Rego, usada pelo Open Policy Agent, permite descrever lógicas complexas, se necessário. E, se você preferir outra ferramenta de políticas, ela também deve funcionar.

Quem é o autor deste software?

Mais um exemplo rápido. Nele, usamos o parlay para enriquecer nosso SBOM e, em seguida, usamos jq e awk para exibir informações úteis. Neste caso, extraímos o nome do autor de cada pacote. Mais uma vez, essas informações geralmente não estão em um SBOM com apenas os elementos mínimos.

$ snyk sbom --format cyclonedx1.4+json | parlay e enrich - | jq -r '(.components[] | [.name, .author]) | @tsv' | awk '{print $1; $1=""; print}'
nio4r
 Socketry
puma
 Puma
prometheus-client
 Prometheus
puma-metrics

rack
 Official Rack repositories
rack-test
 Official Rack repositories
rake
 The Ruby Programming Language
rspec-support
 RSpec
rspec-core
 RSpec
diff-lcs
 Austin Ziegler
rspec-expectations
 RSpec
rspec-mocks
 RSpec
rspec
 RSpec
ruby2_keywords
 The Ruby Programming Language
mustermann
 Sinatra
rack-protection
 Sinatra
tilt
 Jeremy Evans
sinatra
 Sinatra

Há muitas outras coisas que você pode fazer com dados de SBOM mais completos, além de muitos outros dados úteis para enriquecer SBOMs. Conte para nós o que você gostaria de ver e compartilhe exemplos dos seus experimentos com o parlay.