Tutorial: como saber sobre vulnerabilidades de imagem

Este tutorial mostra como usar o Container Analysis para verificar se uma imagem de contêiner armazenada no Container Registry tem vulnerabilidades e listar as vulnerabilidades de alta gravidade.

Objetivos

Este tutorial inclui as etapas a seguir:

  1. Criar uma imagem do Docker com vulnerabilidades conhecidas
  2. Enviar a imagem para o Container Registry do projeto
  3. Usar o Container Analysis para fazer uma varredura inicial e analisar a imagem
  4. Exibir vulnerabilidades identificadas pelo Container Analysis
  5. Listar as vulnerabilidades mais graves da imagem

Custos

Neste tutorial, usamos componentes faturáveis do Google Cloud Platform. Consulte a página de preços para mais informações.

Use a calculadora de preços para gerar uma estimativa de custos baseada na projeção de uso.

Novos usuários do GCP podem se qualificar para uma avaliação gratuita.

Antes de começar

Para usar o Container Analysis, é necessário ativar e configurar o Container Analysis e o Container Registry.

  1. Faça login na sua Conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do GCP, acesse a página Gerenciar recursos e selecione ou crie um projeto.

    Acessar a página Gerenciar recursos

  3. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

  4. Ativar Container Registry and Container Scanning APIs.

    Ativar as APIs

  5. Instale e inicialize o SDK do Cloud.
  6. Se você ainda não fez isso, siga um destes procedimentos para conseguir as permissões do IAM necessárias. Se você for o proprietário do projeto, pule esta etapa.
    • Para ver ocorrências, é necessário ter a seguinte permissão:
      containeranalysis.notes.listOccurrences
    • Como alternativa, é possível atribuir o seguinte papel predefinido do IAM, que concede automaticamente as permissões necessárias:
      Container Analysis Occurrences Viewer
  7. Instale o Docker. Se você estiver usando um sistema operacional baseado em Linux, como Ubuntu ou Debian, adicione seu nome de usuário ao grupo docker para executar o Docker sem usar sudo:
    sudo usermod -a -G docker ${USER}

    Talvez seja necessário reiniciar o sistema depois de adicionar seu nome de usuário ao grupo docker.

  8. Abra o Docker. Para garantir que o Docker esteja ativo, execute o seguinte comando do Docker, que retorna a hora e a data atuais:
  9. docker run busybox date

Criação de uma imagem do Docker

Para este tutorial, crie a seguinte imagem do Docker para que você tenha uma imagem para enviar ao Container Registry. Você usará um ambiente de execução do Python com vulnerabilidades conhecidas que serão identificadas pelo Container Analysis. Ela contém um pequeno aplicativo da web do Python. Esse aplicativo usa a biblioteca da web Flask para disponibilizar uma página da web que exibe a mensagem "Hello, World!”

Para criar a imagem do Docker, siga estas etapas:

  1. Crie um diretório para armazenar os três arquivos de imagem do Docker.

  2. Nesse diretório, crie três arquivos: Dockerfile, requirements.txt e app.py. Consulte os exemplos abaixo de como o conteúdo de cada arquivo precisa ser:

Dockerfile

# The Dockerfile defines the image's environment
# Import Python runtime and set up working directory
# This specified runtime has known vulnerabilities so that vulnerability
# scanning can be tested.
FROM python:2.7-slim
WORKDIR /app
ADD . /app

# Install any necessary dependencies
RUN pip install -r requirements.txt

# Open port 80 for serving the webpage
EXPOSE 80

# Run app.py when the container launches
CMD ["python", "app.py"]

requirements.txt

# This file defines the image's dependencies
Flask

app.py

# The Docker image contains the following code
from flask import Flask
import os
import socket

app = Flask(__name__)

@app.route("/")
def hello():
    html = "<h3>Hello, World!</h3>"
    return html

if __name__ == "__main__":
  app.run(host='0.0.0.0', port=80)

Para criar a imagem do Docker, execute o seguinte comando a partir do diretório que contém os arquivos dela:

docker build -t vulnerabilities-tutorial-image .

Você criou uma imagem do Docker na máquina local.

Adicionar a imagem ao Container Registry

Configurar docker para usar a ferramenta de linha de comando gcloud como um auxiliar de credencial

Antes de enviar ou extrair imagens, configure o Docker para usar a ferramenta de linha de comando gcloud a fim de autenticar as solicitações para o Container Registry. Para isso, execute o seguinte comando (você só precisa fazer isso uma vez):

gcloud auth configure-docker

Marcar a imagem com um nome de registro

Antes de enviar a imagem do Docker ao Container Registry, marque-a com seu nome de registro. Ao fazer isso, você configura o comando docker push para enviar a imagem para um local específico. Para este guia de início rápido, o local do host é gcr.io.

Para marcar a imagem do Docker, execute este comando:

docker tag vulnerabilities-tutorial-image gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1

em que:

  • [PROJECT-ID] é o ID do projeto do Console do Google Cloud Platform que você precisa adicionar ao comando;
  • gcr.io é o nome do host;
  • vulnerabilities-tutorial-image é o nome da imagem do Docker;
  • tag1 é a tag que você está adicionando à imagem do Docker (o Docker aplicará a tag padrão latest se você não tiver especificado uma)

Agora você está pronto para enviar a imagem ao Container Registry.

Enviar a imagem ao Container Registry

Depois que o docker tiver sido configurado para usar o gcloud como um auxiliar de credencial e a imagem local estiver marcada com o nome do registro, você poderá enviá-la para o Container Registry.

Basta executar o comando a seguir:

docker push gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1

[PROJECT-ID] é o ID do projeto do Console do Google Cloud Platform. Caso o ID do projeto contenha dois pontos (:), consulte Projetos com escopo de domínio.

Quando você envia uma imagem para um novo local de host, o serviço cria um intervalo de armazenamento subjacente exclusivo para seu projeto. Para ver as imagens hospedadas pelo Container Registry, use o Console do GCP ou acesse o nome do registro da imagem no navegador da web: http://gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image.

Como realizar a varredura inicial e visualizar os resultados da análise

O Container Analysis executa automaticamente uma varredura inicial e uma análise da imagem. Ele cria uma ocorrência de descoberta, que inclui as informações coletadas dessa varredura inicial. O Container Analysis também atualiza a ocorrência de descoberta com o status atual da varredura.

A amostra de código a seguir pesquisa o status atual da varredura inicial para saber quando as informações de vulnerabilidade estão disponíveis para visualização.

Java

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.DiscoveryOccurrence;
import io.grafeas.v1.DiscoveryOccurrence.AnalysisStatus;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import java.io.IOException;
import java.lang.InterruptedException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class PollDiscoveryOccurrenceFinished {
  // Repeatedly query the Container Analysis API for the latest discovery occurrence until it is
  // either in a terminal state, or the timeout value has been exceeded
  public static Occurrence pollDiscoveryOccurrenceFinished(String resourceUrl, String projectId,
      long timeoutSeconds) throws IOException, TimeoutException, InterruptedException {
    // String resourceUrl = "https://gcr.io/project/image@sha256:123";
    // String projectId = "my-project-id";
    // long timeoutSeconds = 30;
    final String projectName = ProjectName.format(projectId);
    long deadline = System.currentTimeMillis() + timeoutSeconds * 1000;

    // Initialize client that will be used to send requests. After completing all of your requests,
    // call the "close" method on the client to safely clean up any remaining background resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();

    // find the discovery occurrence using a filter string
    Occurrence discoveryOccurrence = null;
    // vulbnerability discovery occurrences are always associated with the
    // PACKAGE_VULNERABILITY note in the "goog-analysis" GCP project
    String filter =  String.format("resourceUrl=\"%s\" AND noteProjectId=\"%s\" AND noteId=\"%s\"",
        resourceUrl, "goog-analysis",  "PACKAGE_VULNERABILITY");
    while (discoveryOccurrence == null) {
      for (Occurrence o : client.listOccurrences(projectName, filter).iterateAll()) {
        if (o.getDiscovery() != null) {
          // there should be only one valid discovery occurrence returned by the given filter
          discoveryOccurrence = o;
        }
      }
      TimeUnit.SECONDS.sleep(1);
      // check for timeout
      if (System.currentTimeMillis() > deadline) {
        throw new TimeoutException("discovery occurrence not found");
      }
    }

    // wait for discovery occurrence to enter a terminal state
    AnalysisStatus status = AnalysisStatus.PENDING;
    while (status != AnalysisStatus.FINISHED_SUCCESS
        && status != AnalysisStatus.FINISHED_FAILED
        && status != AnalysisStatus.FINISHED_UNSUPPORTED) {
      // update the occurrence state
      discoveryOccurrence = client.getOccurrence(discoveryOccurrence.getName());
      status = discoveryOccurrence.getDiscovery().getAnalysisStatus();
      TimeUnit.SECONDS.sleep(1);
      // check for timeout
      if (System.currentTimeMillis() > deadline) {
        throw new TimeoutException("discovery occurrence not in terminal state");
      }
    }
    return discoveryOccurrence;
  }
}

Go

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Go.


import (
	"context"
	"fmt"
	"time"

	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
	"google.golang.org/api/iterator"
	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// pollDiscoveryOccurrenceFinished returns the discovery occurrence for a resource once it reaches a finished state.
func pollDiscoveryOccurrenceFinished(resourceURL, projectID string, timeout time.Duration) (*grafeaspb.Occurrence, error) {
	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
	// timeout := time.Duration(5) * time.Second
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	client, err := containeranalysis.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", err)
	}
	defer client.Close()

	// ticker is used to poll once per second.
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	// Find the discovery occurrence using a filter string.
	var discoveryOccurrence *grafeaspb.Occurrence
	for discoveryOccurrence == nil {
		select {
		case <-ctx.Done():
			return nil, fmt.Errorf("timeout while retrieving discovery occurrence")
		case <-ticker.C:
			req := &grafeaspb.ListOccurrencesRequest{
				Parent: fmt.Sprintf("projects/%s", projectID),
				// Vulnerability discovery occurrences are always associated with the
				// PACKAGE_VULNERABILITY note in the "goog-analysis" GCP project.
				Filter: fmt.Sprintf(`resourceUrl=%q AND noteProjectId="goog-analysis" AND noteId="PACKAGE_VULNERABILITY"`, resourceURL),
			}
			it := client.GetGrafeasClient().ListOccurrences(ctx, req)
			// Only one occurrence should ever be returned by ListOccurrences
			// and the given filter.
			result, err := it.Next()
			if err == iterator.Done {
				break
			}
			if err != nil {
				return nil, fmt.Errorf("it.Next: %v", err)
			}
			if result.GetDiscovery() != nil {
				discoveryOccurrence = result
			}
		}
	}

	// Wait for the discovery occurrence to enter a terminal state.
	for {
		select {
		case <-ctx.Done():
			return nil, fmt.Errorf("timeout waiting for terminal state")
		case <-ticker.C:
			// Update the occurrence.
			req := &grafeaspb.GetOccurrenceRequest{Name: discoveryOccurrence.GetName()}
			updated, err := client.GetGrafeasClient().GetOccurrence(ctx, req)
			if err != nil {
				return nil, fmt.Errorf("GetOccurrence: %v", err)
			}
			switch updated.GetDiscovery().GetAnalysisStatus() {
			case grafeaspb.DiscoveryOccurrence_FINISHED_SUCCESS,
				grafeaspb.DiscoveryOccurrence_FINISHED_FAILED,
				grafeaspb.DiscoveryOccurrence_FINISHED_UNSUPPORTED:
				return discoveryOccurrence, nil
			}
		}
	}
}

Node.js

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Node.js (em inglês).

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const projectId = 'your-project-id', // Your GCP Project ID
// const imageUrl = 'https://gcr.io/my-project/my-image:123', // Image to attach metadata to
// const retries = 5 // The number of retries to listen for the new Pub/Sub messages

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

const formattedParent = client.getGrafeasClient().projectPath(projectId);

let filter = `resourceUrl="${imageUrl}" AND noteProjectId="goog-analysis" AND noteId="PACKAGE_VULNERABILITY"`;

// Repeatedly query the Container Analysis API for the latest discovery occurrence until it is
// either in a terminal state, or the timeout value has been exceeded
const pRetry = require('p-retry');
const discoveryOccurrence = await pRetry(
  async () => {
    const [occurrences] = await client.getGrafeasClient().listOccurrences({
      parent: formattedParent,
      filter: filter,
    });
    if (occurrences.length < 0) {
      throw new Error('No occurrences found for ' + imageUrl);
    }
    return occurrences[0];
  },
  {
    retries: retries,
  }
);

// Wait for discovery occurrence to enter a terminal state or the timeout value has been exceeded
const finishedOccurrence = await pRetry(
  async () => {
    let status = 'PENDING';
    const [updated] = await client.getGrafeasClient().getOccurrence({
      name: discoveryOccurrence.name,
    });
    status = updated.discovery.analysisStatus;
    if (
      status !== 'FINISHED_SUCCESS' &&
      status !== 'FINISHED_FAILED' &&
      status !== 'FINISHED_UNSUPPORTED'
    ) {
      throw new Error('Timeout while retrieving discovery occurrence');
    }
    return updated;
  },
  {
    retries: retries,
  }
);
console.log(
  `Found discovery occurrence ${finishedOccurrence.name}.  Status: ${finishedOccurrence.discovery.analysisStatus}`
);

Ruby

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Ruby (em inglês).

# resource_url    = "The URL of the resource associated with the occurrence.
#                    e.g. https://gcr.io/project/image@sha256:123"
# timeout_seconds = "The number of seconds to wait for the discovery
#                    occurrence"
# project_id      = "Your Google Cloud project ID"

require "grafeas"

deadline = Time.now + timeout_seconds

# Initialize the client
client = Grafeas.new
formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id

# Find the discovery occurrence using a filter string
discovery_occurrence = nil
while discovery_occurrence.nil?
  begin
    filter = 'resourceUrl="#{resource_url}" ' \
             'AND noteProjectId="goog-analysis" ' \
             'AND noteId="PACKAGE_VULNERABILITY"'
    # Only the discovery occurrence should be returned for the given filter
    discovery_occurrence = client.list_occurrences(formatted_parent, filter: filter).first
  rescue StandardError # If there is an error, keep trying until the deadline
    puts "discovery occurrence not yet found"
  ensure
    # check for timeout
    sleep 1
    if Time.now > deadline
      raise "Timeout while retrieving discovery occurrence."
    end
  end
end

# Wait for the discovery occurrence to enter a terminal state
status = Grafeas::V1::DiscoveryOccurrence::AnalysisStatus::PENDING
while status != :FINISHED_SUCCESS &&
      status != :FINISHED_FAILED &&
      status != :FINISHED_UNSUPPORTED
  # Update occurrence
  begin
    updated = client.get_occurrence discovery_occurrence.name
    status = updated.discovery.analysis_status
  rescue StandardError # If there is an error, keep trying until the deadline
    puts "discovery occurrence not yet in terminal state"
  ensure
    # check for timeout
    sleep 1
    if Time.now > deadline
      raise "Timeout while retrieving discovery occurrence."
    end
  end
end
puts "Found discovery occurrence #{updated.name}."
puts "Status: #{updated.discovery.analysis_status}"

Python

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Python (em inglês).

def poll_discovery_finished(resource_url, timeout_seconds, project_id):
    """Returns the discovery occurrence for a resource once it reaches a
    terminal state."""
    # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
    # timeout_seconds = 20
    # project_id = 'my-gcp-project'

    import time
    from grafeas.grafeas_v1.gapic.enums import DiscoveryOccurrence
    from google.cloud.devtools import containeranalysis_v1

    deadline = time.time() + timeout_seconds

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    project_name = grafeas_client.project_path(project_id)

    discovery_occurrence = None
    while discovery_occurrence is None:
        time.sleep(1)
        filter_str = 'resourceUrl="{}" \
                      AND noteProjectId="goog-analysis" \
                      AND noteId="PACKAGE_VULNERABILITY"'.format(resource_url)
        result = grafeas_client.list_occurrences(project_name, filter_str)
        # only one occurrence should ever be returned by ListOccurrences
        # and the given filter
        for item in result:
            discovery_occurrence = item
        if time.time() > deadline:
            raise RuntimeError('timeout while retrieving discovery occurrence')

    status = DiscoveryOccurrence.AnalysisStatus.PENDING
    while status != DiscoveryOccurrence.AnalysisStatus.FINISHED_UNSUPPORTED \
            and status != DiscoveryOccurrence.AnalysisStatus.FINISHED_FAILED \
            and status != DiscoveryOccurrence.AnalysisStatus.FINISHED_SUCCESS:
        time.sleep(1)
        updated = grafeas_client.get_occurrence(discovery_occurrence.name)
        status = updated.discovery.analysis_status
        if time.time() > deadline:
            raise RuntimeError('timeout while waiting for terminal state')
    return discovery_occurrence

Quando o status da verificação é FINISHED_SUCCESS, a lista de vulnerabilidades pode ser exibida.

Como listar todas as vulnerabilidades associadas a uma imagem

Vulnerabilidades conhecidas são armazenadas como notas. O Container Analysis cria uma ocorrência para cada instância de uma nota que encontra durante a análise da imagem. À medida que o Container Analysis coleta novas informações sobre vulnerabilidades, ele atualiza a lista de ocorrências automaticamente.

É possível recuperar informações sobre notas e ocorrências usando o Console do GCP, a ferramenta de linha de comando gcloud ou a API Container Analysis. Além disso, a API é compatível com várias expressões de filtro para recuperar informações específicas sobre notas ou ocorrências.

O código a seguir recupera as vulnerabilidades encontradas para uma imagem.

Java

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class VulnerabilityOccurrencesForImage {
  // Retrieve a list of vulnerability occurrences assoviated with a resource
  public static List<Occurrence> findVulnerabilityOccurrencesForImage(String resourceUrl,
      String projectId) throws IOException {
    // String resourceUrl = "https://gcr.io/project/image@sha256:123";
    // String projectId = "my-project-id";
    final String projectName = ProjectName.format(projectId);
    String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl);

    // Initialize client that will be used to send requests. After completing all of your requests,
    // call the "close" method on the client to safely clean up any remaining background resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
    LinkedList<Occurrence> vulnerabilitylist = new LinkedList<Occurrence>();
    for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
      vulnerabilitylist.add(o);
    }
    return vulnerabilitylist;
  }
}

Go

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Go.


import (
	"context"
	"fmt"

	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
	"google.golang.org/api/iterator"
	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// findVulnerabilityOccurrencesForImage retrieves all vulnerability Occurrences associated with a resource.
func findVulnerabilityOccurrencesForImage(resourceURL, projectID string) ([]*grafeaspb.Occurrence, error) {
	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
	ctx := context.Background()
	client, err := containeranalysis.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", err)
	}
	defer client.Close()

	req := &grafeaspb.ListOccurrencesRequest{
		Parent: fmt.Sprintf("projects/%s", projectID),
		Filter: fmt.Sprintf("resourceUrl = %q kind = %q", resourceURL, "VULNERABILITY"),
	}

	var occurrenceList []*grafeaspb.Occurrence
	it := client.GetGrafeasClient().ListOccurrences(ctx, req)
	for {
		occ, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return nil, fmt.Errorf("occurrence iteration error: %v", err)
		}
		occurrenceList = append(occurrenceList, occ)
	}

	return occurrenceList, nil
}

Node.js

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Node.js (em inglês).

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const projectId = 'your-project-id', // Your GCP Project ID
// const imageUrl = 'https://gcr.io/my-project/my-image:123' // Image to attach metadata to

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

const formattedParent = client.getGrafeasClient().projectPath(projectId);

// Retrieve a list of vulnerability occurrences assoviated with a resource
const [occurrences] = await client.getGrafeasClient().listOccurrences({
  parent: formattedParent,
  filter: `kind = "VULNERABILITY" AND resourceUrl = "${imageUrl}"`,
});

if (occurrences.length) {
  console.log(`All Vulnerabilities for ${imageUrl}`);
  occurrences.forEach(occurrence => {
    console.log(`${occurrence.name}:`);
  });
} else {
  console.log('No occurrences found.');
}

Ruby

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Ruby (em inglês).

# resource_url = "The URL of the resource associated with the occurrence
#                e.g. https://gcr.io/project/image@sha256:123"
# project_id   = "The Google Cloud project ID of the vulnerabilities to find"

require "grafeas"

# Initialize the client
client = Grafeas.new

formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
client.list_occurrences formatted_parent, filter: filter

Python

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Python (em inglês).

def find_vulnerabilities_for_image(resource_url, project_id):
    """"Retrieves all vulnerability occurrences associated with a resource."""
    # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
    # project_id = 'my-gcp-project'

    from google.cloud.devtools import containeranalysis_v1

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    project_name = grafeas_client.project_path(project_id)

    filter_str = 'kind="VULNERABILITY" AND resourceUrl="{}"'\
        .format(resource_url)
    return list(grafeas_client.list_occurrences(project_name, filter_str))

Como listar vulnerabilidades de alta gravidade

Cada vulnerabilidade tem um nível de gravidade associado. O Container Analysis usa informações de nível de gravidade fornecidas pelas distribuições Linux compatíveis. Se os níveis de gravidade específicos da distribuição estiverem indisponíveis, os níveis atribuídos serão baseados nas pontuações do CVSS.

Para priorizar planos de correção de vulnerabilidades, é possível refinar a lista de vulnerabilidades para que ela mostre apenas as mais graves.

A amostra de código a seguir recupera uma lista de vulnerabilidades de uma imagem que recebeu a classificação de gravidade alta ou crítica.

Java

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Java.

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Severity;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class HighVulnerabilitiesForImage {
  // Retrieve a list of vulnerability occurrences with a severity level of 'HIGH' or greater
  public static List<Occurrence> findHighSeverityVulnerabilitiesForImage(String resourceUrl,
      String projectId) throws IOException {
    // String resourceUrl = "https://gcr.io/project/image@sha256:123";
    // String projectId = "my-project-id";
    final String projectName = ProjectName.format(projectId);
    String filterStr = String.format("kind=\"VULNERABILITY\" AND resourceUrl=\"%s\"", resourceUrl);

    // Initialize client that will be used to send requests. After completing all of your requests,
    // call the "close" method on the client to safely clean up any remaining background resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
    LinkedList<Occurrence> vulnerabilitylist = new LinkedList<Occurrence>();
    for (Occurrence o : client.listOccurrences(projectName, filterStr).iterateAll()) {
      Severity severity = o.getVulnerability().getSeverity();
      if (severity == Severity.HIGH || severity == Severity.CRITICAL) {
        vulnerabilitylist.add(o);
      }
    }
    return vulnerabilitylist;
  }
}

Go

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Go.


import (
	"context"
	"fmt"

	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
	"google.golang.org/api/iterator"
	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// findHighSeverityVulnerabilitiesForImage retrieves a list of only high vulnerability occurrences associated with a resource.
func findHighSeverityVulnerabilitiesForImage(resourceURL, projectID string) ([]*grafeaspb.Occurrence, error) {
	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
	ctx := context.Background()
	client, err := containeranalysis.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", err)
	}
	defer client.Close()

	req := &grafeaspb.ListOccurrencesRequest{
		Parent: fmt.Sprintf("projects/%s", projectID),
		Filter: fmt.Sprintf("resourceUrl = %q kind = %q", resourceURL, "VULNERABILITY"),
	}

	var occurrenceList []*grafeaspb.Occurrence
	it := client.GetGrafeasClient().ListOccurrences(ctx, req)
	for {
		occ, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return nil, fmt.Errorf("occurrence iteration error: %v", err)
		}

		severityLevel := occ.GetVulnerability().GetSeverity()
		if severityLevel == grafeaspb.Severity_HIGH || severityLevel == grafeaspb.Severity_CRITICAL {
			occurrenceList = append(occurrenceList, occ)
		}
	}

	return occurrenceList, nil
}

Node.js

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Node.js (em inglês).

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const projectId = 'your-project-id', // Your GCP Project ID
// const imageUrl = 'https://gcr.io/my-project/my-image:123' // Image to attach metadata to

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

const formattedParent = client.getGrafeasClient().projectPath(projectId);

// Retrieve a list of vulnerability occurrences with a severity level of 'HIGH' or greater
const [occurrences] = await client.getGrafeasClient().listOccurrences({
  parent: formattedParent,
  filter: `kind = "VULNERABILITY" AND resourceUrl = "${imageUrl}"`,
});

if (occurrences.length) {
  console.log(`High Severity Vulnerabilities for ${imageUrl}`);
  occurrences.forEach(occurrence => {
    if (
      occurrence.vulnerability.severity === 'HIGH' ||
      occurrence.vulnerability.severity === 'CRITICAL'
    ) {
      console.log(`${occurrence.name}:`);
    }
  });
} else {
  console.log('No occurrences found.');
}

Ruby

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Ruby (em inglês).

# resource_url = "The URL of the resource associated with the occurrence,
#                 e.g. https://gcr.io/project/image@sha256:123"
# project_id   = "The Google Cloud project ID of the vulnerabilities to find"

require "grafeas"

# Initialize the client
client = Grafeas.new

formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
vulnerability_list = client
                     .list_occurrences(formatted_parent, filter: filter)
# Filter the list to include only "high" and "critical" vulnerabilities
vulnerability_list.select do |item|
  item.vulnerability.severity == :HIGH || item.vulnerability.severity == :CRITICAL
end

Python

Para saber como instalar e usar a biblioteca de cliente do Container Registry, consulte Bibliotecas de cliente do Container Registry. Para mais informações, consulte a documentação de referência da API Container Registry Python (em inglês).

def find_high_severity_vulnerabilities_for_image(resource_url, project_id):
    """Retrieves a list of only high vulnerability occurrences associated
    with a resource."""
    # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
    # project_id = 'my-gcp-project'

    from grafeas.grafeas_v1.gapic.enums import Severity
    from google.cloud.devtools import containeranalysis_v1

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    project_name = grafeas_client.project_path(project_id)

    filter_str = 'kind="VULNERABILITY" AND resourceUrl="{}"'\
        .format(resource_url)
    vulnerabilities = grafeas_client.list_occurrences(project_name, filter_str)
    filtered_list = []
    for v in vulnerabilities:
        if v.severity == Severity.HIGH or v.severity == Severity.CRITICAL:
            filtered_list.append(v)
    return filtered_list

Limpeza

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform, é possível fazer o seguinte:

Como excluir a imagem

Caso você queira apenas remover a imagem do Docker que foi adicionada, execute o comando a seguir para excluir a imagem do Docker do Container Registry.

gcloud container images delete gcr.io/[PROJECT-ID]/vulnerabilities-tutorial-image:tag1 --force-delete-tags

em que [PROJECT-ID] é o ID do projeto do Console do Google Cloud Platform. Caso o ID do projeto contenha dois pontos (:), consulte Projetos com escopo de domínio.

Excluir o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. No Console do GCP, acesse a página "Projetos".

    Acessar a página Projetos

  2. Na lista de projetos, selecione um e clique em Excluir projeto.
  3. Na caixa de diálogo, digite o código do projeto e clique em Encerrar para excluí-lo.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…