Update API verwenden

Überblick

Mit der Update API können Ihre Clientanwendungen verschlüsselte Versionen der Web-Risiko-Listen herunterladen, um sie in einer lokalen Datenbank oder einer speicherinternen Datenbank zu speichern. URLs können dann lokal überprüft werden. Wenn eine Übereinstimmung in der lokalen Datenbank gefunden wird, sendet der Client eine Anfrage an die Web Risk-Server, um zu überprüfen, ob die URL in den Web Risk-Listen enthalten ist.

Lokale Datenbank aktualisieren

Um immer auf dem neuesten Stand zu bleiben, müssen Kunden die Web Risk-Listen in ihrer lokalen Datenbank regelmäßig aktualisieren. Um Bandbreite zu sparen, laden Kunden die Hash-Präfixe der URLs und nicht die URLs selbst herunter. Wenn z. B. "www.badurl.com/" auf einer Web Risk-Liste steht, laden Kunden den SHA256-Hash-Präfix dieser URL und nicht die URL selbst herunter. In den meisten Fällen sind die Hash-Präfixe 4 Byte lang, was bedeutet, dass die durchschnittlichen Bandbreitenkosten für das Herunterladen eines einzelnen Listeneintrags vor der Komprimierung 4 Byte betragen.

Senden Sie zum Aktualisieren der Web Risk-Listen in der lokalen Datenbank eine HTTP-GET-Anfrage an die Methode threatLists.computeDiff:

  • Die HTTP-GET-Anfrage enthält den Namen der zu aktualisierenden Liste sowie Clienteinschränkungen zur Berücksichtigung von Speicher- und Bandbreitenbeschränkungen.
  • Die HTTP-GET-Anfrage gibt entweder eine vollständige Aktualisierung oder eine teilweise Aktualisierung zurück. Die Antwort könnte auch eine empfohlene Wartezeit bis zum nächsten Compute-Diff-Vorgang zurückgeben.

Beispiel: threatLists.computeDiff

HTTP-GET-Anfrage

Im folgenden Beispiel werden die Diffs für die MALWARE Web Risk-Liste angefordert. Weitere Informationen finden Sie in den threatLists.computeDiff-Abfrageparametern und in den Erläuterungen nach dem Codebeispiel.

HTTP-Methode und 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

Senden Sie die Anfrage mithilfe einer der folgenden Optionen:

curl

Führen Sie folgenden Befehl aus:

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

Führen Sie folgenden Befehl aus:

$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

Sie sollten eine JSON-Antwort ähnlich wie diese erhalten:

{
  "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

Web Risk-Listen

Das Feld threatType gibt die Web Risk-Liste an. In diesem Beispiel werden die Diffs für die MALWARE Web Risk-Liste angefordert.

Versionstoken

Das Feld versionToken enthält den aktuellen Clientstatus der Web Risk-Liste. Versionstokens werden im Feld newVersionToken der Antwort threatLists.computeDiff zurückgegeben. Lassen Sie bei ersten Aktualisierungen das Feld versionToken leer.

Größenbeschränkungen

Das Feld maxDiffEntries gibt die Gesamtzahl der Aktualisierungen an, die der Client verwalten kann (im Beispiel 2.048). Das Feld maxDatabaseEntries gibt die Gesamtzahl der Einträge an, die die lokale Datenbank verwalten kann (im Beispiel 4.096). Clients sollten Größenbeschränkungen festlegen, um Speicher- und Bandbreitenbeschränkungen zu schützen und ein Wachstum von Listen zu verhindern. Weitere Informationen finden Sie unter Einschränkungen aktualisieren.

Unterstützte Komprimierungen

Im Feld supportedCompressions sind die vom Client unterstützten Komprimierungstypen aufgeführt. In diesem Beispiel unterstützt der Client nur unkomprimierte Rohdaten. Web Risk unterstützt jedoch zusätzliche Komprimierungstypen. Weitere Informationen finden Sie unter Komprimierung.

HTTP-GET-Antwort

In diesem Beispiel gibt die Antwort eine Teilaktualisierung für die Liste "Web Risk" mit dem angeforderten Komprimierungstyp zurück.

Antworttext

Der Antworttext enthält die Diffs-Informationen (den Antworttyp, die auf die lokale Datenbank anzuwendenden Hinzufügungen und Entfernungen, das neue Versions-Token und eine Prüfsumme).

In diesem Beispiel enthält die Antwort auch eine empfohlene nächste Diff-Zeit. Weitere Informationen finden Sie im Antworttext threatLists.computeDiff und in den Erläuterungen nach dem Codebeispiel.

{
  "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"
}

Datenbank-Diffs

Das Feld responseType gibt eine teilweise Aktualisierung (DIFF) oder eine vollständige Aktualisierung (RESET) an. Im Beispiel werden partielle Diffs zurückgegeben, sodass die Antwort sowohl Hinzufügungen als auch Entfernungen enthält. Es kann mehrere Sätze von Hinzufügungen geben, aber nur einen Satz von Entfernungen. Weitere Informationen finden Sie unter Datenbank-Diffs.

Neues Versionstoken

Das Feld newVersionToken enthält das neue Versionstoken für die neu aktualisierte Web Risk-Liste. Clients müssen den Status des neuen Clients für nachfolgende Aktualisierungsanfragen speichern (das Feld versionToken in der threatLists.computeDiff-Anfrage).

Prüfsummen

Mit der Prüfsumme können Clients prüfen, ob die lokale Datenbank beschädigt ist. Wenn die Prüfsumme nicht übereinstimmt, muss der Client die Datenbank löschen und eine Aktualisierung mit einem leeren versionToken-Feld noch einmal ausführen. Clients in dieser Situation müssen jedoch die Zeitintervalle für Aktualisierungen einhalten. Weitere Informationen finden Sie unter Anfragehäufigkeit.

Das Feld recommendedNextDiff gibt einen Zeitstempel an, bis zu dem der Client warten soll, bevor er eine weitere Aktualisierungsanfrage sendet. Beachten Sie, dass die empfohlene Wartezeit in der Antwort enthalten sein kann. Weitere Informationen finden Sie unter Anfragehäufigkeit.

URLs prüfen

Um zu prüfen, ob sich eine URL auf einer Web Risk-Liste befindet, muss der Client zuerst den Hash und das Hash-Präfix der URL berechnen. Weitere Informationen finden Sie unter URLs und Hashing. Der Client fragt dann die lokale Datenbank ab, um festzustellen, ob eine Übereinstimmung vorliegt. Wenn das Hash-Präfix in der lokalen Datenbank nicht vorhanden ist, wird die URL als sicher eingestuft (d. h. nicht in den Web Risk-Listen).

Wenn das Hash-Präfix in der lokalen Datenbank vorhanden ist (eine Hash-Präfixkollision), muss der Client das Hash-Präfix zur Prüfung an die Web Risk-Server senden. Die Server geben alle SHA 256-Hashes in voller Länge zurück, die das angegebene Hash-Präfix enthalten. Wenn einer dieser Hashs in voller Länge mit dem Hash der betreffenden URL in voller Länge übereinstimmt, wird die URL als unsicher eingestuft. Wenn keiner der Hashes in voller Länge mit dem Hash in voller Länge der betreffenden URL übereinstimmt, wird diese URL als sicher betrachtet.

Google erfährt zu keinem Zeitpunkt, welche URLs Sie untersuchen. Google erfährt zwar die Hash-Präfixe von URLs, die Hash-Präfixe liefern jedoch nur wenige Informationen zu den tatsächlichen URLs.

Senden Sie eine HTTP-GET-Anfrage an die Methode hashes.search, um zu prüfen, ob sich eine URL auf einer Liste mit Webrisiken befindet:

  • Die HTTP-GET-Anfrage enthält das Hash-Präfix der zu überprüfenden URL.
  • Die HTTP-GET-Antwort gibt die übereinstimmenden Hashes in voller Länge sowie die positive und negative Ablaufzeit zurück.

Beispiel: hashes.search

HTTP-GET-Anfrage

Im folgenden Beispiel werden die Namen von zwei Web Risk-Listen und ein Hash-Präfix zum Vergleich und zur Überprüfung gesendet. Weitere Informationen finden Sie in den hashes.search-Abfrageparametern und in den Erläuterungen nach dem Codebeispiel.

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

Web Risk-Listen

Das Feld threatTypes gibt die Web Risk-Listen an. Im Beispiel werden zwei Listen identifiziert: MALWARE und SOCIAL_ENGINEERING.

Bedrohungs-Hash-Präfixe

Das Feld hashPrefix enthält das Hash-Präfix der URL, die Sie prüfen möchten. Dieses Feld muss das genaue Hash-Präfix enthalten, das in der lokalen Datenbank vorhanden ist. Wenn das lokale Hash-Präfix beispielsweise 4 Byte lang ist, muss das Feld hashPrefix 4 Byte lang sein. Wenn das lokale Hash-Präfix auf 7 Byte verlängert wurde, muss das Feld hashPrefix 7 Byte lang sein.

HTTP-GET-Antwort

Im folgenden Beispiel gibt die Antwort die übereinstimmenden Bedrohungen zurück, die die entsprechenden Web Risk-Listen sowie die Ablaufzeiten enthalten.

Antworttext

Der Antworttext enthält die Übereinstimmungsinformationen (die Listennamen und die Hashes in voller Länge und die Cache-Dauer). Weitere Informationen finden Sie im Antworttext hashes.search und in den Erläuterungen nach dem Codebeispiel.

{
  "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"
}

Stimmt überein mit

Das Feld threats gibt übereinstimmende Hashes in voller Länge für das Hash-Präfix zurück. Die URLs, die diesen Hashes entsprechen, gelten als unsicher. Wenn für ein Hash-Präfix keine Übereinstimmung gefunden wird, wird nichts zurückgegeben. Die URL, die diesem Hash-Präfix entspricht, gilt als sicher.

Ablaufzeit

In den Feldern expireTime und negativeExpireTime wird angegeben, wann die Hashes als unsicher bzw. sicher gelten müssen. Weitere Informationen finden Sie unter Caching.