Utilizzo dell'API Update

Panoramica

L'API Update consente alle applicazioni client di scaricare versioni sottoposte ad hashing dei Elenchi Web Risk per l'archiviazione in un database locale o in memoria. Gli URL possono per poi essere controllati localmente. Quando viene trovata una corrispondenza nel database locale, il client invia una richiesta ai server Web Risk per verificare se l'URL sia incluse negli elenchi Web Risk.

Aggiornamento del database locale

Per rimanere al passo con le novità, i clienti sono tenuti ad aggiornare periodicamente gli elenchi di rischi web nel proprio database locale. Per risparmiare larghezza di banda, i client scaricano i prefissi hash degli URL anziché gli URL non elaborati. Ad esempio, se "www.badurl.com/" si trova in un elenco Web Risk, i client scaricano prefisso hash di quell'URL anziché dell'URL stesso. Nella maggior parte dei casi i prefissi hash hanno una lunghezza di 4 byte, il che significa che il costo medio della il download di una singola voce di elenco richiede 4 byte prima della compressione.

Per aggiornare gli elenchi di Web Risk nel database locale, invia una richiesta HTTPGET al metodo threatLists.computeDiff:

  • La richiesta HTTP GET include il nome dell'elenco da aggiornare insieme con vincoli client per tenere conto dei limiti di memoria e larghezza di banda.
  • La risposta HTTP GET restituisce un aggiornamento completo o parziale. La risposta potrebbe anche restituire un tempo di attesa consigliato fino alla successiva operazione di calcolo della differenza.

Esempio: threatLists.computeDiff

Richiesta HTTP GET

Nell'esempio seguente, le differenze per l'elenco MALWARE Web Risk sono richiesta. Per maggiori dettagli, consulta i parametri di query threatLists.computeDiff e le spiegazioni che seguono l'esempio di codice.

Metodo HTTP e URL:

GET https://webrisk.googleapis.com/v1/threatLists:computeDiff?threatType=MALWARE&versionToken=Gg4IBBADIgYQgBAiAQEoAQ%3D%3D&constraints.maxDiffEntries=2048&constraints.maxDatabaseEntries=4096&constraints.supportedCompressions=RAW&key=API_KEY

Per inviare la richiesta, scegli una delle seguenti opzioni:

curl

Esegui questo comando:

curl -X GET \
"https://webrisk.googleapis.com/v1/threatLists:computeDiff?threatType=MALWARE&versionToken=Gg4IBBADIgYQgBAiAQEoAQ%3D%3D&constraints.maxDiffEntries=2048&constraints.maxDatabaseEntries=4096&constraints.supportedCompressions=RAW&key=API_KEY"

PowerShell

Esegui questo comando:

$headers = @{  }

Invoke-WebRequest `
-Method GET `
-Headers $headers `
-Uri "https://webrisk.googleapis.com/v1/threatLists:computeDiff?threatType=MALWARE&versionToken=Gg4IBBADIgYQgBAiAQEoAQ%3D%3D&constraints.maxDiffEntries=2048&constraints.maxDatabaseEntries=4096&constraints.supportedCompressions=RAW&key=API_KEY" | Select-Object -Expand Content

Dovresti ricevere una risposta JSON simile alla seguente:

{
  "recommendedNextDiff": "2020-01-08T19:41:45.436722194Z",
  "responseType": "RESET",
  "additions": {
    "rawHashes": [
      {
        "prefixSize": 4,
        "rawHashes": "AArQMQAMoUgAPn8lAE..."
      }
    ]
  },
  "newVersionToken": "ChAIARAGGAEiAzAwMSiAEDABEPDyBhoCGAlTcIVL",
  "checksum": {
    "sha256": "wy6jh0+MAg/V/+VdErFhZIpOW+L8ulrVwhlV61XkROI="
  }
}

Java


import com.google.cloud.webrisk.v1.WebRiskServiceClient;
import com.google.protobuf.ByteString;
import com.google.webrisk.v1.CompressionType;
import com.google.webrisk.v1.ComputeThreatListDiffRequest;
import com.google.webrisk.v1.ComputeThreatListDiffRequest.Constraints;
import com.google.webrisk.v1.ComputeThreatListDiffResponse;
import com.google.webrisk.v1.ThreatType;
import java.io.IOException;

public class ComputeThreatListDiff {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    // The threat list to update. Only a single ThreatType should be specified per request.
    ThreatType threatType = ThreatType.MALWARE;

    // The current version token of the client for the requested list. If the client does not have
    // a version token (this is the first time calling ComputeThreatListDiff), this may be
    // left empty and a full database snapshot will be returned.
    ByteString versionToken = ByteString.EMPTY;

    // The maximum size in number of entries. The diff will not contain more entries
    // than this value. This should be a power of 2 between 2**10 and 2**20.
    // If zero, no diff size limit is set.
    int maxDiffEntries = 1024;

    // Sets the maximum number of entries that the client is willing to have in the local database.
    // This should be a power of 2 between 2**10 and 2**20. If zero, no database size limit is set.
    int maxDatabaseEntries = 1024;

    // The compression type supported by the client.
    CompressionType compressionType = CompressionType.RAW;

    computeThreatDiffList(threatType, versionToken, maxDiffEntries, maxDatabaseEntries,
        compressionType);
  }

  // Gets the most recent threat list diffs. These diffs should be applied to a local database of
  // hashes to keep it up-to-date.
  // If the local database is empty or excessively out-of-date,
  // a complete snapshot of the database will be returned. This Method only updates a
  // single ThreatList at a time. To update multiple ThreatList databases, this method needs to be
  // called once for each list.
  public static void computeThreatDiffList(ThreatType threatType, ByteString versionToken,
      int maxDiffEntries, int maxDatabaseEntries, CompressionType compressionType)
      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. After completing all of your requests, call
    // the `webRiskServiceClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (WebRiskServiceClient webRiskServiceClient = WebRiskServiceClient.create()) {

      Constraints constraints = Constraints.newBuilder()
          .setMaxDiffEntries(maxDiffEntries)
          .setMaxDatabaseEntries(maxDatabaseEntries)
          .addSupportedCompressions(compressionType)
          .build();

      ComputeThreatListDiffResponse response = webRiskServiceClient.computeThreatListDiff(
          ComputeThreatListDiffRequest.newBuilder()
              .setThreatType(threatType)
              .setVersionToken(versionToken)
              .setConstraints(constraints)
              .build());

      // The returned response contains the following information:
      // https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#computethreatlistdiffresponse
      // Type of response: DIFF/ RESET/ RESPONSE_TYPE_UNSPECIFIED
      System.out.println(response.getResponseType());
      // List of entries to add and/or remove.
      // System.out.println(response.getAdditions());
      // System.out.println(response.getRemovals());

      // New version token to be used the next time when querying.
      System.out.println(response.getNewVersionToken());

      // Recommended next diff timestamp.
      System.out.println(response.getRecommendedNextDiff());

      System.out.println("Obtained threat list diff.");
    }
  }
}

Python

from google.cloud import webrisk_v1
from google.cloud.webrisk_v1 import ComputeThreatListDiffResponse


def compute_threatlist_diff(
    threat_type: webrisk_v1.ThreatType,
    version_token: bytes,
    max_diff_entries: int,
    max_database_entries: int,
    compression_type: webrisk_v1.CompressionType,
) -> ComputeThreatListDiffResponse:
    """Gets the most recent threat list diffs.

    These diffs should be applied to a local database of hashes to keep it up-to-date.
    If the local database is empty or excessively out-of-date,
    a complete snapshot of the database will be returned. This Method only updates a
    single ThreatList at a time. To update multiple ThreatList databases, this method needs to be
    called once for each list.

    Args:
        threat_type: The threat list to update. Only a single ThreatType should be specified per request.
            threat_type = webrisk_v1.ThreatType.MALWARE

        version_token: The current version token of the client for the requested list. If the
            client does not have a version token (this is the first time calling ComputeThreatListDiff),
            this may be left empty and a full database snapshot will be returned.

        max_diff_entries: The maximum size in number of entries. The diff will not contain more entries
            than this value. This should be a power of 2 between 2**10 and 2**20.
            If zero, no diff size limit is set.
            max_diff_entries = 1024

        max_database_entries: Sets the maximum number of entries that the client is willing to have in the local database.
            This should be a power of 2 between 2**10 and 2**20. If zero, no database size limit is set.
            max_database_entries = 1024

        compression_type: The compression type supported by the client.
            compression_type = webrisk_v1.CompressionType.RAW

    Returns:
        The response which contains the diff between local and remote threat lists. In addition to the threat list,
        the response also contains the version token and the recommended time for next diff.
    """

    webrisk_client = webrisk_v1.WebRiskServiceClient()

    constraints = webrisk_v1.ComputeThreatListDiffRequest.Constraints()
    constraints.max_diff_entries = max_diff_entries
    constraints.max_database_entries = max_database_entries
    constraints.supported_compressions = [compression_type]

    request = webrisk_v1.ComputeThreatListDiffRequest()
    request.threat_type = threat_type
    request.version_token = version_token
    request.constraints = constraints

    response = webrisk_client.compute_threat_list_diff(request)

    # The returned response contains the following information:
    # https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#computethreatlistdiffresponse
    # Type of response: DIFF/ RESET/ RESPONSE_TYPE_UNSPECIFIED
    print(response.response_type)
    # New version token to be used the next time when querying.
    print(response.new_version_token)
    # Recommended next diff timestamp.
    print(response.recommended_next_diff)

    return response

Elenchi Web Risk

Il campo threatType identifica l'elenco Web Risk. Nella Ad esempio, vengono richieste le differenze per l'elenco Web Risk di MALWARE.

Token di versione

Il campo versionToken contiene lo stato attuale del client Elenco Web Risk. I token di versione vengono restituiti nel campo newVersionToken della risposta threatLists.computeDiff. Per gli aggiornamenti iniziali, lascia vuoto il campo versionToken.

Vincoli di dimensioni

Il campo maxDiffEntries specifica il numero totale di aggiornamenti che il client può gestire (nell'esempio, 2048). Il campo maxDatabaseEntries specifica il numero totale di voci che il database locale può gestire (nell' esempio, 4096). I clienti devono impostare limiti di dimensione per proteggere la memoria e le limitazioni della larghezza di banda e per proteggersi dall'aumento dell'elenco. Per vedi Aggiornare i vincoli).

Compressioni supportate

Il campo supportedCompressions elenca i tipi di compressione supportati dal cliente. Nell'esempio, il client supporta solo dati non elaborati e non compressi. Web Risk, tuttavia, supporta altri tipi di compressione. Per ulteriori informazioni, consulta Compressione.

Risposta GET HTTP

In questo esempio, la risposta restituisce un aggiornamento parziale per l'elenco Rischi web utilizzando il tipo di compressione richiesto.

Corpo della risposta

Il corpo della risposta include le informazioni sulle differenze (il tipo di risposta, le aggiunte e le rimozioni da applicare al database locale, il token della nuova versione e un checksum).

Nell'esempio, la risposta include anche data/ora della differenza successiva consigliata. Per ulteriori dettagli, consulta Corpo della risposta threatLists.computeDiff e le spiegazioni che seguono l'esempio di codice.

{
  "responseType" :   "DIFF",
  "recommendedNextDiff": "2019-12-31T23:59:59.000000000Z",
  "additions": {
    "compressionType": "RAW",
    "rawHashes": [{
      "prefixSize": 4,
      "rawHashes":  "rnGLoQ=="
    }]
  },
  "removals": {
    "rawIndices": {
      "indices": [0, 2, 4]
    }
  },
  "newVersionToken": "ChAIBRADGAEiAzAwMSiAEDABEAFGpqhd",
  "checksum": {
    "sha256": "YSgoRtsRlgHDqDA3LAhM1gegEpEzs1TjzU33vqsR8iM="
  },
  "recommendedNextDiff": "2019-07-17T15:01:23.045123456Z"
}

Differenze nel database

Il campo responseType indica un aggiornamento parziale (DIFF) o totale (RESET). Nell'esempio vengono restituite differenze parziali, pertanto la risposta include sia le aggiunte sia le rimozioni. Potrebbero essere presenti più set di aggiunte, ma un solo set di rimozioni. Per ulteriori informazioni, vedi Differenze database.

Token nuova versione

Il campo newVersionToken contiene il nuovo token di versione per il nuovo token Elenco Web Risk. I client devono salvare il nuovo stato per le richieste di aggiornamento (il campo versionToken nella Richiesta threatLists.computeDiff.

Checksum

Il checksum consente ai client di verificare che il database locale non abbia subito alcun corruzione. Se il checksum non corrisponde, il client deve cancellare il database e emettere nuovamente un aggiornamento con un campo versionToken vuoto. Tuttavia, i clienti di questa situazione deve comunque rispettare gli intervalli di tempo per gli aggiornamenti. Per maggiori informazioni informazioni, consulta Frequenza della richiesta.

Il campo recommendedNextDiff indica un timestamp fino al momento in cui il cliente deve attendere prima di inviare un'altra richiesta di aggiornamento. Tieni presente che il periodo di attesa consigliato può essere incluso o meno nella risposta. Per maggiori dettagli, consulta la sezione Frequenza delle richieste.

Controllo degli URL

Per verificare se un URL è presente in un elenco di Web Risk, il client deve prima calcolare l'hash e il prefisso dell'hash dell'URL. Per maggiori dettagli, consulta la sezione URL e hashing. Il client esegue quindi una query sul database locale determinare se esiste una corrispondenza. Se il prefisso hash non è presente nella locale, l'URL viene considerato sicuro (ovvero non sulla elenchi Web Risk).

Se il prefisso hash è presente nel database locale (una collisione del prefisso hash), il client deve inviarlo ai server Web Risk per la verifica. I server restituiranno tutti gli hash SHA 256 di lunghezza intera che contengono il prefisso dell'hash specificato. Se uno di questi hash completi corrisponde all'hash completo dell'URL in questione, l'URL è considerato non sicuro. Se nessuno degli hash completi corrisponde all'hash completo dell'URL in discussione, l'URL è considerato sicuro.

Google non apprende in alcun momento gli URL che stai esaminando. Google apprendere i prefissi hash degli URL, ma questi ultimi non forniscono molto informazioni sugli URL effettivi.

Per verificare se un URL è in un elenco Web Risk, invia una richiesta GET HTTP in hashes.search :

  • La richiesta HTTP GET include il prefisso hash dell'URL da controllare.
  • La risposta HTTP GET restituisce gli hash completi corrispondenti insieme ai relativi tempi di scadenza positivi e negativi.

Esempio: hashes.search

Richiesta HTTP GET

Nell'esempio seguente, i nomi di due elenchi Web Risk e un hash vengono inviati per il confronto e la verifica. Per ulteriori dettagli, consulta hashes.search parametri di query e le spiegazioni che seguono l'esempio di codice.

curl \
  -H "Content-Type: application/json" \
  "https://webrisk.googleapis.com/v1/hashes:search?key=YOUR_API_KEY&threatTypes=MALWARE&threatTypes=SOCIAL_ENGINEERING&hashPrefix=WwuJdQ%3D%3D"

Java


import com.google.cloud.webrisk.v1.WebRiskServiceClient;
import com.google.protobuf.ByteString;
import com.google.webrisk.v1.SearchHashesRequest;
import com.google.webrisk.v1.SearchHashesResponse;
import com.google.webrisk.v1.SearchHashesResponse.ThreatHash;
import com.google.webrisk.v1.ThreatType;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;

public class SearchHashes {

  public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
    // TODO(developer): Replace these variables before running the sample.
    // A hash prefix, consisting of the most significant 4-32 bytes of a SHA256 hash.
    // For JSON requests, this field is base64-encoded. Note that if this parameter is provided
    // by a URI, it must be encoded using the web safe base64 variant (RFC 4648).
    String uri = "http://example.com";
    String encodedUri = Base64.getUrlEncoder().encodeToString(uri.getBytes(StandardCharsets.UTF_8));
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    byte[] encodedHashPrefix = digest.digest(encodedUri.getBytes(StandardCharsets.UTF_8));

    // The ThreatLists to search in. Multiple ThreatLists may be specified.
    // For the list on threat types, see: https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threattype
    List<ThreatType> threatTypes = Arrays.asList(ThreatType.MALWARE, ThreatType.SOCIAL_ENGINEERING);

    searchHash(ByteString.copyFrom(encodedHashPrefix), threatTypes);
  }

  // Gets the full hashes that match the requested hash prefix.
  // This is used after a hash prefix is looked up in a threatList and there is a match.
  // The client side threatList only holds partial hashes so the client must query this method
  // to determine if there is a full hash match of a threat.
  public static void searchHash(ByteString encodedHashPrefix, List<ThreatType> threatTypes)
      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. After completing all of your requests, call
    // the `webRiskServiceClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (WebRiskServiceClient webRiskServiceClient = WebRiskServiceClient.create()) {

      // Set the hashPrefix and the threat types to search in.
      SearchHashesResponse response = webRiskServiceClient.searchHashes(
          SearchHashesRequest.newBuilder()
              .setHashPrefix(encodedHashPrefix)
              .addAllThreatTypes(threatTypes)
              .build());

      // Get all the hashes that match the prefix. Cache the returned hashes until the time
      // specified in threatHash.getExpireTime()
      // For more information on response type, see: https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threathash
      for (ThreatHash threatHash : response.getThreatsList()) {
        System.out.println(threatHash.getHash());
      }
      System.out.println("Completed searching threat hashes.");
    }
  }
}

Python

from google.cloud import webrisk_v1


def search_hashes(hash_prefix: bytes, threat_type: webrisk_v1.ThreatType) -> list:
    """Gets the full hashes that match the requested hash prefix.

    This is used after a hash prefix is looked up in a threatList and there is a match.
    The client side threatList only holds partial hashes so the client must query this method
    to determine if there is a full hash match of a threat.

    Args:
        hash_prefix: A hash prefix, consisting of the most significant 4-32 bytes of a SHA256 hash.
            For JSON requests, this field is base64-encoded. Note that if this parameter is provided
            by a URI, it must be encoded using the web safe base64 variant (RFC 4648).
            Example:
                uri = "http://example.com"
                sha256 = sha256()
                sha256.update(base64.urlsafe_b64encode(bytes(uri, "utf-8")))
                hex_string = sha256.digest()

        threat_type: The ThreatLists to search in. Multiple ThreatLists may be specified.
            For the list on threat types, see:
            https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threattype
            threat_type = [webrisk_v1.ThreatType.MALWARE, webrisk_v1.ThreatType.SOCIAL_ENGINEERING]

    Returns:
        A hash list that contain all hashes that matches the given hash prefix.
    """
    webrisk_client = webrisk_v1.WebRiskServiceClient()

    # Set the hashPrefix and the threat types to search in.
    request = webrisk_v1.SearchHashesRequest()
    request.hash_prefix = hash_prefix
    request.threat_types = [threat_type]

    response = webrisk_client.search_hashes(request)

    # Get all the hashes that match the prefix. Cache the returned hashes until the time
    # specified in threat_hash.expire_time
    # For more information on response type, see:
    # https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threathash
    hash_list = []
    for threat_hash in response.threats:
        hash_list.append(threat_hash.hash)
    return hash_list

Elenchi di Web Risk

Il campo threatTypes identifica gli elenchi di Web Risk. Nell'esempio vengono identificati due elenchi: MALWARE e SOCIAL_ENGINEERING.

Prefissi degli hash delle minacce

Il campo hashPrefix contiene il prefisso dell'hash dell'URL che vuoi controllare. Questo campo deve contenere l'esatto prefisso hash presente nella un database locale. Ad esempio, se il prefisso hash locale è di 4 byte, allora il campo hashPrefix deve contenere 4 byte. Se il prefisso hash locale era allungato a 7 byte, il campo hashPrefix deve avere una lunghezza di 7 byte.

Risposta GET HTTP

Nell'esempio seguente, la risposta restituisce le minacce corrispondenti, contenenti gli elenchi di Web Risk a cui corrispondono, insieme alle date di scadenza.

Corpo della risposta

Il corpo della risposta include le informazioni sulla corrispondenza (i nomi degli elenchi, gli hash di lunghezza completa e le durate della cache). Per ulteriori dettagli, consulta Corpo della risposta hashes.search e le spiegazioni che seguono l'esempio di codice.

{
  "threats": [{
      "threatTypes": ["MALWARE"],
      "hash": "WwuJdQx48jP-4lxr4y2Sj82AWoxUVcIRDSk1PC9Rf-4="
      "expireTime": "2019-07-17T15:01:23.045123456Z"
    }, {
      "threatTypes": ["MALWARE", "SOCIAL_ENGINEERING"],
      "hash": "WwuJdQxaCSH453-uytERC456gf45rFExcE23F7-hnfD="
      "expireTime": "2019-07-17T15:01:23.045123456Z"
    },
  }],
  "negativeExpireTime": "2019-07-17T15:01:23.045123456Z"
}

Corrisponde a

Il campo threats restituisce hash completi corrispondenti per il prefisso hash. Gli URL corrispondenti a questi hash sono considerati non sicuri. Se non viene trovata alcuna corrispondenza per un prefisso hash, non viene restituito nulla; l'URL corrispondente a quel prefisso hash è considerato sicuro.

Ora di scadenza

I campi expireTime e negativeExpireTime indicano fino a quando gli hash devono essere considerati rispettivamente non sicuri o sicuri. Per ulteriori dettagli, consulta la sezione Memorizzazione nella cache.