Elenco dei risultati di sicurezza utilizzando l'API Security Command Center

Il modello dei risultati di Security Command Center mostra i potenziali rischi per la sicurezza degli asset in un progetto o un'organizzazione. Un risultato si riferisce sempre a una risorsa specifica in Security Command Center.

Questa guida mostra come utilizzare le librerie client di Security Command Center per accedere ai risultati. Ogni risultato appartiene a una fonte. La maggior parte dei rilevatori o dei fornitori di risultati produce risultati all'interno della stessa origine.

I ruoli IAM per Security Command Center possono essere concessi a livello di organizzazione, cartella o progetto. La possibilità di visualizzare, modificare, creare o aggiornare risultati, asset e origini di sicurezza dipende dal livello per cui ti è stato concesso l'accesso. Per scoprire di più sui ruoli di Security Command Center, consulta la sezione Controllo dell'accesso.

Prima di iniziare

Prima di configurare una fonte, devi completare le seguenti operazioni:

Dimensioni pagina

Tutte le API di elenco di Security Command Center sono impaginate. Ogni risposta restituisce una pagina di risultati e un token per restituire la pagina successiva. Le dimensioni della pagina sono configurabili. La dimensione predefinita della pagina è 10. Puoi impostarlo su un minimo di 1 e un massimo di 1000.

Conservazione dei risultati

A seconda del livello di Security Command Center, i risultati rimangono disponibili per essere elencati o interrogati per periodi di tempo specifici. Per ulteriori informazioni sulla conservazione dei dati di Security Command Center, vedi Conservazione dei dati.

Elenca tutti i risultati

gcloud

Per elencare tutti i risultati in un progetto, una cartella o un'organizzazione, esegui questo comando:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
  --location=LOCATION

Sostituisci quanto segue:

  • PARENT_TYPE: il livello della gerarchia delle risorse per cui elencare i risultati; utilizza organizations, folders o projects.
  • PARENT_ID: l'ID numerico dell'organizzazione, della cartella o del progetto oppure l'ID progetto alfanumerico.
  • LOCATION: la posizione di Security Command Center in cui elencare i risultati; se la residenza dei dati è abilitata, utilizza eu, sa o us; altrimenti, utilizza il valore global.

Per altri esempi, esegui:

gcloud scc findings list --help

Per esempi nella documentazione, consulta gcloud scc findings list.

Vai

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv2"
	"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listFindings prints all findings in orgID to w. orgID is the numeric
// identifier of the organization.
func listFindings(w io.Writer, orgID string) error {
	// orgID := "12321311"
	// Instantiate a context and a security service client to make API calls.
	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListFindingsRequest{
		// List findings across all sources.
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}/sources/-/locations/global"
		//		"projects/{projectId}/sources/-/locations/global"
		//		"folders/{folderId}/sources/-/locations/global"
		Parent: fmt.Sprintf("organizations/%s/sources/-/locations/global", orgID),
	}
	it := client.ListFindings(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("it.Next: %w", err)
		}
		finding := result.Finding
		fmt.Fprintf(w, "Finding Name: %s, ", finding.Name)
		fmt.Fprintf(w, "Resource Name %s, ", finding.ResourceName)
		fmt.Fprintf(w, "Category: %s\n", finding.Category)
	}
	return nil
}

Java


import com.google.cloud.securitycenter.v2.ListFindingsRequest;
import com.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;
import com.google.cloud.securitycenter.v2.SecurityCenterClient;
import java.io.IOException;

public class ListAllFindings {

  public static void main(String[] args) throws IOException {
    // organizationId: The source to list all findings for.
    // You can also use project/ folder as the parent resource.
    String organizationId = "google-cloud-organization-id";

    // Specify the location to list the findings.
    String location = "global";

    // The source id to scope the findings.
    String sourceId = "source-id";

    listAllFindings(organizationId, sourceId, location);
  }

  // List all findings under a given parent resource.
  public static void listAllFindings(String organizationId, String sourceId, String location)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {
      ListFindingsRequest request =
          ListFindingsRequest.newBuilder()
              // To list findings across all sources, use "-".
              .setParent(
                  String.format("organizations/%s/sources/%s/locations/%s", organizationId,
                      sourceId,
                      location))
              .build();

      for (ListFindingsResult result : client.listFindings(request).iterateAll()) {
        System.out.printf("Finding: %s", result.getFinding().getName());
      }
      System.out.println("\nListing complete.");
    }
  }
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;

// Creates a new client.
const client = new SecurityCenterClient();

// TODO(developer): Update the following for your own environment.
const organizationId = '1081635000895';
const location = 'global';

// Required. Name of the source the findings belong to. If no location is
// specified, the default is global. The following list shows some examples:
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
// - `folders/[folder_id]/sources/[source_id]`
// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`
// - `projects/[project_id]/sources/[source_id]`
// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`
// To groupBy across all sources provide a source_id of `-`.
const parent = `organizations/${organizationId}/sources/-/locations/${location}`;

// Build the list findings request.
const listFindingsRequest = {
  parent,
};

async function listAllFindings() {
  // Call the API.
  const iterable = client.listFindingsAsync(listFindingsRequest);
  let count = 0;

  for await (const response of iterable) {
    // Just print a few for demonstration.
    if (count > 5) break;
    console.log(
      `${++count} ${response.finding.name} ${response.finding.resourceName}`
    );
  }
}

await listAllFindings();

Python

def list_all_findings(organization_id, source_name, location_id) -> int:
    """
    lists all findings for a source
    Args:
       organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
       source_name: is the resource path for a source that has been created
       location_id: GCP location id; example: 'global'
    Returns:
        int: returns the count of all findings for a source
    """
    from google.cloud import securitycenter_v2

    # Create a client.
    client = securitycenter_v2.SecurityCenterClient()
    parent = f"organizations/{organization_id}"
    all_sources = f"{parent}/sources/{source_name}/locations/{location_id}"

    # Create the request dictionary
    request = {"parent": all_sources}

    # Print the request for debugging
    print("Request: ", request)

    finding_result_iterator = client.list_findings(request={"parent": all_sources})
    for count, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                count, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    return finding_result_iterator

L'output per ogni risultato è simile al seguente:

{
  "finding": {
    "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID",
    "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID",
    "resourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "state": "ACTIVE",
    "category": "Malware: Cryptomining Bad Domain",
    "sourceProperties": {
      "sourceId": {
        "projectNumber": "PROJECT_NUMBER",
        "customerOrganizationNumber": "ORGANIZATION_ID"
      },
      "detectionCategory": {
        "technique": "cryptomining",
        "indicator": "domain",
        "ruleName": "bad_domain",
        "subRuleName": "cryptomining"
      },
      "detectionPriority": "LOW",
      "affectedResources": [
        {
          "gcpResourceName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER"
        }
      ],
      "evidence": [
        {
          "sourceLogId": {
            "projectId": "PROJECT_ID",
            "resourceContainer": "projects/PROJECT_ID",
            "timestamp": {
              "seconds": "1636566099",
              "nanos": 5.41483849E8
            },
            "insertId": "INSERT_ID"
          }
        }
      ],
      "properties": {
        "domains": ["DOMAIN"],
        "instanceDetails": "/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_ID",
        "network": {
          "project": "PROJECT_ID",
          "location": "ZONE"
        },
        "dnsContexts": [
          {
            "authAnswer": true,
            "sourceIp": "SOURCE_IP_ADDRESS",
            "queryName": "DOMAIN",
            "queryType": "A",
            "responseCode": "NXDOMAIN"
          }
        ],
        "vpc": {
          "vpcName": "default"
        }
      },
      "findingId": "FINDING_ID",
      "contextUris": {
        "mitreUri": {
          "displayName": "MITRE Link",
          "url": "https://attack.mitre.org/techniques/T1496/"
        },
        "virustotalIndicatorQueryUri": [
          {
            "displayName": "VirusTotal Domain Link",
            "url": "https://www.virustotal.com/gui/domain/DOMAIN/detection"
          }
        ],
        "cloudLoggingQueryUri": [
          {
            "displayName": "Cloud Logging Query Link",
            "url": "https://console.cloud.google.com/logs/query;query\u003dtimestamp%3D%222021-11-10T17:41:39.541483849Z%22%0AinsertId%3D%22INSERT_ID%22%0Aresource.labels.project_id%3D%22PROJECT_ID%22?project\u003dPROJECT_ID"
          }
        ],
        "relatedFindingUri": {}
      }
    },
    "securityMarks": {
      "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks"
    },
    "eventTime": "2021-11-10T17:41:41.594Z",
    "createTime": "2021-11-10T17:41:42.014Z",
    "severity": "LOW",
    "workflowState": "NEW",
    "canonicalName": "projects/PROJECT_NUMBER/sources/SOURCE_ID/findings/FINDING_ID",
    "mute": "UNDEFINED",
    "findingClass": "THREAT",
    "indicator": {
      "domains": ["DOMAIN"]
    }
  },
  "resource": {
    "name": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "projectName": "//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER",
    "projectDisplayName": "PROJECT_ID",
    "parentName": "//cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID",
    "parentDisplayName": "PARENT_NAME",
    "type": "google.cloud.resourcemanager.Project",
    "displayName": "PROJECT_ID"
  }
}

Filtrare i risultati

Un progetto, una cartella o un'organizzazione potrebbero avere molti risultati. L'esempio precedente non utilizza un filtro, quindi vengono restituiti tutti i record dei risultati.

Per ottenere informazioni solo sui campi che ti interessano, puoi utilizzare i filtri di ricerca. Questi filtri sono simili alle clausole "where" nelle istruzioni SQL, ma anziché alle colonne, si applicano agli oggetti restituiti dall'API.

L'esempio seguente elenca solo i risultati che hanno una categoria "MEDIUM_RISK_ONE". Diversi fornitori di risultati (noti anche come origini di sicurezza) utilizzano diversi insiemi di categorie. Per determinare le categorie che puoi utilizzare nel filtro, consulta la documentazione del fornitore di risultati.

gcloud

Utilizza il seguente comando per filtrare i risultati:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
  --location=LOCATION \
  --source=SOURCE_ID \
  --filter="FILTER"

Sostituisci quanto segue:

  • PARENT_TYPE: il livello della gerarchia delle risorse per cui elencare i risultati; utilizza organizations, folders o projects.
  • PARENT_ID: l'ID numerico dell'organizzazione, della cartella o del progetto oppure l'ID progetto alfanumerico.
  • LOCATION: la posizione di Security Command Center in cui elencare i risultati con un filtro; se la residenza dei dati è abilitata, utilizza eu, sa o us; altrimenti, utilizza il valore global.
  • SOURCE_ID: l'ID dell'origine di sicurezza che fornisce il tipo di problema.
  • FILTER: il filtro che devi utilizzare. Ad esempio, il seguente filtro restituisce i risultati della categoria MEDIUM_RISK_ONE soltanto:
    --filter="category=\"MEDIUM_RISK_ONE\""

Per altri esempi, esegui:

gcloud scc findings list --help

Per esempi nella documentazione, consulta gcloud scc findings list.

Vai

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv2"
	"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listFilteredFindings prints findings with category 'MEDIUM_RISK_ONE' for a
// specific source to w. sourceName is the full resource name of the source
// to search for findings under.
func listFilteredFindings(w io.Writer, sourceName string) error {
	// Specific source:
	// 		sourceName := "{parent}/sources/{sourceId}"
	// All sources:
	// 		sourceName := "{parent}/sources/-"
	// where,
	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	// Instantiate a context and a security service client to make API calls.
	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %w", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListFindingsRequest{
		Parent: sourceName,
		Filter: `category="MEDIUM_RISK_ONE"`,
	}
	it := client.ListFindings(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("it.Next: %w", err)
		}
		finding := result.Finding
		fmt.Fprintf(w, "Finding Name: %s, ", finding.Name)
		fmt.Fprintf(w, "Resource Name %s, ", finding.ResourceName)
		fmt.Fprintf(w, "Category: %s\n", finding.Category)
	}
	return nil
}

Java


import com.google.cloud.securitycenter.v2.ListFindingsRequest;
import com.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;
import com.google.cloud.securitycenter.v2.SecurityCenterClient;
import java.io.IOException;

public class ListFindingsWithFilter {

  public static void main(String[] args) throws IOException {
    // TODO: Replace the variables within {}
    // organizationId: Google Cloud Organization id.
    // You can also use project/ folder as the parent resource.
    String organizationId = "google-cloud-organization-id";

    // Specify the location to list the findings.
    String location = "global";

    // The source id to scope the findings.
    String sourceId = "source-id";

    listFilteredFindings(organizationId, sourceId, location);
  }

  // List filtered findings under a source.
  public static void listFilteredFindings(String organizationId, String sourceId, String location)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      // Use any one of the following formats:
      //  * organizations/{organization_id}/sources/{source_id}/locations/{location}
      //  * folders/{folder_id}/sources/{source_id}/locations/{location}
      //  * projects/{project_id}/sources/{source_id}/locations/{location}
      String parent = String.format("organizations/%s/sources/%s/locations/%s", organizationId,
          sourceId,
          location);

      // Listing all findings of category "MEDIUM_RISK_ONE".
      String filter = "category=\"MEDIUM_RISK_ONE\"";

      ListFindingsRequest request =
          ListFindingsRequest.newBuilder()
              .setParent(parent)
              .setFilter(filter)
              .build();

      for (ListFindingsResult result : client.listFindings(request).iterateAll()) {
        System.out.printf("Finding: %s", result.getFinding().getName());
      }
      System.out.println("\nListing complete.");
    }
  }
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;

// Creates a new client.
const client = new SecurityCenterClient();

// TODO(developer): Update the following for your own environment.
const organizationId = '1081635000895';
const location = 'global';

// Required. Name of the source to groupBy. If no location is specified,
// finding is assumed to be in global.
//  The following list shows some examples:
// - `organizations/[organization_id]/sources/[source_id]`
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
// - `folders/[folder_id]/sources/[source_id]`
// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`
// - `projects/[project_id]/sources/[source_id]`
// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`
// To groupBy across all sources provide a source_id of `-`.
const parent = `organizations/${organizationId}/sources/-/locations/${location}`;

// Listing all findings of category "MEDIUM_RISK_ONE".
const filter = 'category="MEDIUM_RISK_ONE"';

// Build the list findings with filter request.
const listFilteredFindingsRequest = {
  parent,
  filter,
};

async function listFilteredFindings() {
  // Call the API.
  const iterable = client.listFindingsAsync(listFilteredFindingsRequest);
  let count = 0;
  console.log('Findings:');
  for await (const response of iterable) {
    // Just print a few for demonstration.
    if (count > 5) break;
    console.log(
      `${++count} ${response.finding.name} ${response.finding.resourceName}`
    );
  }
}
await listFilteredFindings();

Python

def list_filtered_findings(organization_id, source_name, location_id) -> int:
    """
    lists filtered findings for a source
    Args:
        organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
        source_name: is the resource path for a source that has been created
        location_id: GCP location id; example: 'global'
    Returns:
         int: returns the filtered findings for a source
    """
    count = 0
    from google.cloud import securitycenter_v2

    # Create a new client.
    client = securitycenter_v2.SecurityCenterClient()
    parent = f"organizations/{organization_id}"
    all_sources = f"{parent}/sources/{source_name}/locations/{location_id}"
    finding_result_iterator = client.list_findings(
        request={"parent": all_sources, "filter": 'severity="LOW"'}
    )
    # Iterate an print all finding names and the resource they are
    # in reference to.
    for count, finding_result in enumerate(finding_result_iterator):
        print(
            "{}: name: {} resource: {}".format(
                count, finding_result.finding.name, finding_result.finding.resource_name
            )
        )
    return count

Security Command Center supporta anche array e oggetti JSON completi come potenziali tipi di proprietà. Puoi filtrare in base a:

  • Elementi array
  • Oggetti JSON completi con corrispondenza parziale della stringa all'interno dell'oggetto
  • Campi secondari dell'oggetto JSON

Operatori supportati

Le istruzioni di query per i risultati di Security Command Center supportano gli operatori supportati dalla maggior parte delle API Google Cloud .

Il seguente elenco mostra l'utilizzo di vari operatori:

  • state="ACTIVE" AND NOT mute="MUTED"
  • create_time>"2023-08-15T19:05:32.428Z"
  • resource.parent_name:"prod"
  • severity="CRITICAL" OR severity="HIGH"

Il seguente elenco mostra tutti gli operatori e le funzioni supportati nelle istruzioni di query per i risultati:

  • Per le stringhe:
    • = per la piena uguaglianza
    • : per la corrispondenza parziale delle stringhe
  • Per i numeri (tranne int64):
    • <, >, <=, >= per le disuguaglianze
    • =, != per l'uguaglianza
  • Per i numeri (int 64):
    • =, != per l'uguaglianza
  • Per i valori booleani:
    • = per l'uguaglianza
  • Per le relazioni logiche:
    • AND
    • OR
    • NOT o -
  • Per raggruppare le espressioni:
    • (, ) (parentesi)
  • Per gli array:
    • contains(), una funzione per eseguire query sui risultati con un campo array che contiene almeno un elemento che corrisponde al filtro specificato
    • containsOnly(), una funzione per eseguire query sui risultati con un campo array che contiene solo elementi che corrispondono al filtro specificato
  • Per gli indirizzi IP:
    • inIpRange(), una funzione per eseguire query sugli indirizzi IP all'interno di un intervallo CIDR specificato

Filtro per indirizzi IP

Alcune proprietà dei risultati includono indirizzi IP. Puoi filtrare i risultati in base a indirizzi IP specifici o a un intervallo di indirizzi IP.

Gli indirizzi IP vengono visualizzati come stringhe in una serie di risultati e proprietà dei risultati, tra cui:

  • access.caller_ip
  • connections.destinationIp
  • connections.sourceIp
  • indicator.ip_addresses

Per filtrare in base a un indirizzo IP specifico, puoi utilizzare l'operatore di uguaglianza, come mostrato nell'esempio seguente:

access.caller_ip="192.0.2.0"

Per filtrare i risultati in base a un intervallo di indirizzi IP, utilizza la funzione inIpRange. Utilizzando la funzione inIpRange, filtri i risultati in modo da visualizzare solo quelli che contengono un indirizzo IP all'interno di un intervallo CIDR specificato. Utilizzando l'operazione NOT con inIpRange, puoi filtrare i risultati in modo da visualizzare solo quelli che contengono un indirizzo IP al di fuori dell'intervallo CIDR specificato.

Il seguente esempio mostra la sintassi della funzione inIpRange:

inIpRange(IP_FINDING_FIELD, "CIDR_RANGE")

Se l'indirizzo IP si trova in un elemento di un array in un campo di un risultato che contiene un array, utilizza la seguente sintassi con la funzione contains e la funzione inIpRange:

contains(ATTRIBUTE_WITH_ARRAY, inIpRange(IP_FINDING_FIELD, "CIDR_RANGE"))

Nell'esempio seguente, la funzione inIpRange valuta ogni elemento destination_ip dell'array contenuto nel campo connections finding per un indirizzo IP che rientra nell'intervallo CIDR definito da 192.0.2.0/24:

contains(connections, inIpRange(destination_ip, "192.0.2.0/24"))

L'esempio seguente mostra un comando gcloud CLI che utilizza la funzione inIpRange per filtrare i risultati che hanno un indirizzo IP nel campo connections.source_ip che rientra in un intervallo, ma non in un altro. Il campo connections è un campo di tipo array, quindi viene utilizzata la funzione contains:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(connections, inIpRange(source_ip, \"2001:db8::/32\")) \
      AND NOT contains(connections, inIpRange(source_ip, \"192.0.2.0/24\"))"

Esempio di oggetto JSON

Gli esempi riportati più avanti in questa pagina presuppongono che il seguente oggetto JSON sia un attributo di un problema:

{
  "outer_object": {
    "middle_object": {
      "deeply_nested_object": {
        "x": 123
      },
      "y": "some-string-value"
    },
    "list_middle_object": [
      {
        "v": 321,
        "w": [
          {
            "a": 3,
            "b": 4
          }
        ]
      }
    ],
    "z": "some-other-string-value",
    "u": [
      "list-element-1",
      "list-element-2",
      "list-element-3"
    ]
  }
}

Esempio di filtro dei risultati

Supponiamo che l'esempio JSON precedente sia un attributo di un problema denominato my_property. L'esempio seguente include query per i risultati che hanno l'oggetto come proprietà. Puoi anche utilizzare questi filtri con altri filtri utilizzando AND e OR nella query.

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.deeply_nested_object.x = 123"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.y = \"some-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.middle_object.y : \"string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.z = \"some-other-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.z : \"other-string-value\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-1\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-2\""

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="my_property.outer_object.u : \"list-element-3\""

Filtri secondari per i campi di tipo array

Quando chiami ListFindings, puoi utilizzare una corrispondenza di sottostringa :, che esegue un singolo controllo per una corrispondenza parziale della stringa nell'intero contenuto dell'array. In alternativa, puoi eseguire un filtro secondario direttamente sugli elementi dell'array e sui relativi campi secondari utilizzando una delle seguenti funzioni:

  • La funzione contains() per restituire i risultati quando uno qualsiasi degli elementi dell'array contiene il valore specificato.

  • La funzione containsOnly() per restituire i risultati solo se tutti gli elementi dell'array corrispondono al filtro secondario.

Entrambe queste funzioni supportano le funzionalità di query dei filtri secondari, ad esempio:

  • Corrispondenza esatta degli elementi: corrisponde agli elementi dell'array che contengono la stringa esatta, "example".
  • Operazioni con numeri specifici: corrispondenza degli elementi dell'array maggiori o uguali a 100.
  • Filtro complesso in base alle strutture degli array: corrispondenza degli elementi dell'array che contengono la proprietà x con un valore corrispondente y.

Formato della funzione contains()

La funzione contains() ha il seguente formato:

contains(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Sostituisci quanto segue:

  • ARRAY_ATTRIBUTE_NAME: un campo o un sottocampo di tipo array (un elenco).
  • SUBFILTER: un'espressione che definisce i valori da cercare nell'array. Il formato del filtro secondario varia a seconda che ARRAY_ATTRIBUTE_NAME sia un array di oggetti o un array di elementi di tipo primitivo. Se ARRAY_ATTRIBUTE_NAME è un array di oggetti che contengono array nidificati, puoi utilizzare un filtro secondario con ambito per specificare che tutte le condizioni devono essere soddisfatte all'interno dello stesso elemento ARRAY_ATTRIBUTE_NAME.

L'API Security Command Center restituisce i risultati in cui ARRAY_ATTRIBUTE_NAME contiene almeno un elemento che soddisfa SUBFILTER.

Formato della funzione containsOnly()

La funzione containsOnly() ha il seguente formato:

containsOnly(ARRAY_ATTRIBUTE_NAME, SUBFILTER)

Sostituisci quanto segue:

  • ARRAY_ATTRIBUTE_NAME: un campo o un sottocampo di tipo array (un elenco). Quando esegui query utilizzando l'API Security Command Center, puoi utilizzare la funzione containsOnly() per qualsiasi attributo array disponibile.
  • SUBFILTER: un'espressione che definisce i valori da cercare nell'array. Il formato del filtro secondario varia a seconda che ARRAY_ATTRIBUTE_NAME sia un array di oggetti o un array di elementi di tipo primitivo. Se ARRAY_ATTRIBUTE_NAME è un array di oggetti che contengono array nidificati, puoi utilizzare un sottofiltro con ambito per specificare che tutte le condizioni devono essere soddisfatte all'interno dello stesso elemento ARRAY_ATTRIBUTE_NAME.

L'API Security Command Center restituisce i risultati in cui tutti gli elementi di ARRAY_ATTRIBUTE_NAME corrispondono a SUBFILTER.

Filtro secondario per un array di oggetti

Di seguito è riportato un estratto dell'esempio JSON precedente. In questo caso, il campo list_middle_object è un array di oggetti:

    "list_middle_object": [
      {
        "v": 321,
        "w": [
          {
            "a": 3,
            "b": 4
          }
        ]
      }
    ]

Le seguenti query di esempio cercano risultati in cui almeno uno degli elementi nel campo list_middle_object ha un sottocampo v con un valore maggiore o uguale a 321:

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.list_middle_object, v  >= 321)"

Per esempi pratici che utilizzano le funzioni contains() e containsOnly(), consulta Risultati che contengono valori di array specifici.

Filtro secondario per un array contenente elementi di tipo primitivo

I tipi primitivi sono stringhe, numeri e valori booleani. Per utilizzare la funzione contains() su un array che contiene tipi primitivi, utilizza la parola chiave speciale elem.

Di seguito è riportato un estratto dell'esempio JSON precedente. In questo caso, il campo u è un array di elementi di tipo primitivo:

"u": ["list-element-1", "list-element-2", "list-element-3"]

L'esempio seguente esegue una query per i risultati in cui almeno uno degli elementi nel campo u è "list-element-1":

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.u, elem = \"list-element-1\")"

Per esempi pratici che utilizzano la funzione contains(), vedi Risultati che contengono valori di array specifici.

Filtro secondario mirato

Di seguito è riportato un estratto dell'esempio JSON precedente. In questo caso, il campo list_middle_object è un array di oggetti e gli oggetti in questo array contengono un array nidificato.

"list_middle_object": [
  {
    "v": 321,
    "w": [
      {
        "a": 3,
        "b": 4
      }
    ]
  }
]

La query nell'esempio seguente viene eseguita per i risultati in cui entrambe le seguenti condizioni sono soddisfatte all'interno dello stesso elemento list_middle_object:

  • Il campo secondario v ha un valore maggiore o uguale a 321.
  • Il campo secondario w non contiene un elemento con una proprietà a uguale a 3.
gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --filter="contains(my_property.outer_object.list_middle_object, v  >= 321 AND -contains(w, a = 3))"

Per esempi pratici che utilizzano la funzione contains(), vedi Risultati che contengono valori di array specifici.

Esempio di ordinamento dei risultati

Puoi ordinare i risultati in base a campi secondari rigorosi che sono tipi primitivi: stringhe, numeri e valori booleani. Supponiamo che l'esempio JSON precedente sia un attributo di ricerca denominato my_property. Il seguente esempio include query per ordinare i campi dei risultati. La parola chiave DESC specifica che il campo che segue deve essere ordinato in ordine decrescente. L'ordine predefinito è crescente.

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.deeply_nested_object.x DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.deeply_nested_object.x"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.y DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.middle_object.y"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.z DESC"

gcloud scc findings list PARENT_TYPE/PARENT_ID \
    --location=LOCATION \
    --source=SOURCE_ID \
    --order-by="my_property.outer_object.z"

Esempi di filtro

Le seguenti sezioni mostrano esempi pratici di ricerca dei filtri.

Filtra i risultati che si sono verificati dopo un determinato momento

Questi filtri di esempio corrispondono ai risultati più recenti dopo mercoledì 5 giugno 2019 alle 22:12:05 GMT. Con il filtro event_time, puoi esprimere l'ora utilizzando i seguenti formati e tipi:

  • Ora Unix epoch (in millisecondi) come valore letterale intero

    "event_time > 1559772725000"
    
  • RFC 3339 come valore letterale stringa

    "event_time > \"2019-06-05T22:34:40+00:00\""
    

Filtrare in base ai campi di tipo array

Il seguente esempio mostra l'utilizzo di una corrispondenza parziale di stringa in un campo di tipo array all'interno di un filtro:

"indicator.domains : \"website.com\""

L'API Security Command Center restituisce qualsiasi risultato con una stringa parziale website.com all'interno dell'array. Ad esempio, corrisponde a un risultato con indicator.domains = [\"onewebsite.com\"] perché "website.com" è una sottostringa in un elemento dell'array.

Nelle sezioni seguenti, i filtri di esempio mostrano alcune opzioni per l'utilizzo del filtro di tipo array avanzato utilizzando la funzione contains().

Filtra in base al campo vulnerability.cve.references

L'esempio seguente restituisce risultati in cui almeno un elemento dell'array vulnerability.cve.references ha sia una proprietà source uguale a SOURCE_OF_REFERENCE sia una proprietà uri che ha FILTERED_URI.

"contains(vulnerability.cve.references, source = \"SOURCE_OF_REFERENCE\" AND uri : \"FILTERED_URI\")"

Sostituisci quanto segue:

Filtra in base al campo indicator.domains

L'esempio seguente restituisce i risultati in cui almeno un dominio indicatore ha sia mycompanyprefix che .ca.

"contains(indicator.domains, elem : \"mycompanyprefix\" AND elem : \".ca\")"

Filtra in base al campo indicator.ip_addresses

L'esempio seguente restituisce i risultati in cui almeno un elemento dell'array indicator.ip_addresses è uguale a IP_ADDRESS.

"contains(indicator.ip_addresses, elem = \"IP_ADDRESS\")"

Sostituisci IP_ADDRESS con un indirizzo IP associato ai risultati che stai cercando.

Filtrare in base agli assegnatari del sistema esterno

L'esempio seguente restituisce i risultati in cui almeno un elemento dell'array external_systems.EXTERNAL_SYSTEM_NAME.assignees è uguale a ASSIGNEE.

"contains(external_systems.EXTERNAL_SYSTEM_NAME.assignees, elem = \"ASSIGNEE\")"

Sostituisci quanto segue:

  • EXTERNAL_SYSTEM_NAME: il nome di un sistema SIEM/SOAR di terze parti, ad esempio demisto.
  • ASSIGNEE: un assegnatario nel sistema esterno.

Filtra in base al campo resource.folders.resource_folder

L'esempio seguente restituisce i risultati in cui almeno un elemento dell'array resource.folders.resource_folder non è uguale a FOLDER_NAME.

"contains(resource.folders.resource_folder, -(elem = \"FOLDER_NAME\"))"

Filtra in base al campo resource.folders.resource_folder_display_name

L'esempio seguente restituisce i risultati in cui almeno un elemento dell'array resource.folders.resource_folder_display_name è uguale a DISPLAY_NAME.

"contains(resource.folders.resource_folder_display_name, elem = \"DISPLAY_NAME\")"

Sostituisci DISPLAY_NAME con il nome definito dall'utente della cartella associata ai risultati che stai cercando.

Il filtro include solo service account specifici

L'esempio seguente restituisce risultati solo quando il valore del membro di ogni voce iam_bindings è uguale a uno degli account di servizio forniti.

containsOnly(iam_bindings, (member = SERVICE_ACCOUNT1 OR member = SERVICE_ACCOUNT2 OR member = "SERVICE_ACCOUNT3 "))

Sostituisci SERVICE_ACCOUNT1, SERVICE_ACCOUNT2 e SERVICE_ACCOUNT3 con gli indirizzi email dei service account.

Per scoprire come utilizzare le funzioni contains() e containsOnly() in un filtro dei risultati, consulta Subfiltri per i campi di tipo array.

Passaggi successivi

Scopri di più sulla configurazione delle notifiche sui risultati.