Menggunakan Update API

Ringkasan

Update API memungkinkan aplikasi klien Anda mendownload versi yang di-hash dari daftar Risiko Web untuk disimpan di database lokal atau dalam memori. URL kemudian dapat diperiksa secara lokal. Jika kecocokan ditemukan di database lokal, klien akan mengirim permintaan ke server Web Risk untuk memverifikasi apakah URL tersebut termasuk dalam daftar Web Risk atau tidak.

Memperbarui database lokal

Agar tetap terbaru, klien harus memperbarui daftar Risiko Web secara berkala di database lokal mereka. Untuk menghemat bandwidth, klien mendownload awalan hash URL, bukan URL mentah. Misalnya, jika "www.badurl.com/" ada dalam daftar Web Risk, klien akan mendownload awalan hash SHA256 URL tersebut, bukan URL itu sendiri. Dalam sebagian besar kasus, awalan hash memiliki panjang 4 byte, yang berarti biaya bandwidth rata-rata untuk mendownload satu entri daftar adalah 4 byte sebelum kompresi.

Untuk memperbarui daftar Risiko Web di database lokal, kirim permintaan HTTP GET ke metode threatLists.computeDiff:

  • Permintaan HTTP GET mencakup nama daftar yang akan diperbarui beserta batasan klien untuk memperhitungkan batasan memori dan bandwidth.
  • Respons HTTP GET menampilkan update penuh atau update sebagian. Respons dapat juga menampilkan waktu tunggu yang direkomendasikan hingga operasi perbedaan komputasi berikutnya.

Contoh: threatLists.computeDiff

Permintaan HTTP GET

Dalam contoh berikut, perbedaan untuk daftar Web Risk MALWARE diminta. Untuk mengetahui detail selengkapnya, lihat parameter kueri threatLists.computeDiff dan penjelasan yang mengikuti contoh kode.

Metode HTTP dan 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

Untuk mengirim permintaan Anda, pilih salah satu opsi berikut:

curl

Jalankan perintah berikut:

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

Jalankan perintah berikut:

$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

Anda akan melihat respons JSON seperti berikut:

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

Daftar Web Risk

Kolom threatType mengidentifikasi daftar Web Risk. Dalam contoh, perbedaan untuk daftar Web Risk MALWARE diminta.

Token versi

Kolom versionToken menyimpan status klien saat ini dari daftar Web Risk. Token Versi ditampilkan di kolom newVersionToken dari respons threatLists.computeDiff. Untuk update awal, biarkan kolom versionToken kosong.

Batasan ukuran

Kolom maxDiffEntries menentukan jumlah total update yang dapat dikelola klien (dalam contoh, 2048). Kolom maxDatabaseEntries menentukan jumlah total entri yang dapat dikelola oleh database lokal (dalam contoh, 4096). Klien harus menetapkan batasan ukuran untuk melindungi batasan memori dan bandwidth serta untuk melindungi dari pertumbuhan daftar. Untuk mengetahui informasi selengkapnya, lihat Batasan Update).

Kompresi yang didukung

Kolom supportedCompressions mencantumkan jenis kompresi yang didukung klien. Dalam contoh, klien hanya mendukung data mentah yang tidak dikompresi. Namun, Web Risk mendukung jenis kompresi tambahan. Untuk mengetahui informasi selengkapnya, lihat Kompresi.

Respons HTTP GET

Dalam contoh ini, respons menampilkan update sebagian untuk daftar Web Risk menggunakan jenis kompresi yang diminta.

Isi respons

Isi respons mencakup informasi perbedaan (jenis respons, penambahan dan penghapusan yang akan diterapkan ke database lokal, token versi baru, dan checksum).

Dalam contoh, respons juga mencakup waktu perbedaan berikutnya yang direkomendasikan. Untuk mengetahui detail selengkapnya, lihat isi respons threatLists.computeDiff dan penjelasan yang mengikuti contoh kode.

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

Perbedaan database

Kolom responseType akan menunjukkan pembaruan sebagian (DIFF) atau penuh (RESET). Dalam contoh ini, perbedaan sebagian ditampilkan, sehingga respons mencakup penambahan dan penghapusan. Mungkin ada beberapa set penambahan, tetapi hanya ada satu set penghapusan. Untuk mengetahui informasi selengkapnya, lihat Perbedaan Database.

Token versi baru

Kolom newVersionToken menyimpan token versi baru untuk daftar Web Risk yang baru diupdate. Klien harus menyimpan status klien baru untuk permintaan update berikutnya (kolom versionToken dalam permintaan threatLists.computeDiff.

Checksums

Checksum memungkinkan klien memverifikasi bahwa database lokal tidak mengalami kerusakan apa pun. Jika checksum tidak cocok, klien harus menghapus database dan menerbitkan ulang update dengan kolom versionToken yang kosong. Namun, klien dalam situasi ini tetap harus mengikuti interval waktu untuk update. Untuk mengetahui informasi selengkapnya, lihat Frekuensi Permintaan.

Kolom recommendedNextDiff menunjukkan stempel waktu hingga kapan klien harus menunggu sebelum mengirim permintaan update lain. Perhatikan bahwa periode tunggu yang direkomendasikan mungkin disertakan atau tidak dalam respons. Untuk mengetahui detail selengkapnya, lihat Frekuensi Permintaan.

Memeriksa URL

Untuk memeriksa apakah suatu URL ada dalam daftar Web Risk, klien harus menghitung hash dan awalan hash URL terlebih dahulu. Untuk mengetahui detailnya, lihat URL dan Hashing. Klien kemudian mengkueri database lokal untuk menentukan apakah ada kecocokan. Jika awalan hash tidak ada di database lokal, maka URL dianggap aman (yaitu, tidak ada di daftar Web Risk).

Jika awalan hash ada di database lokal (terjadi tabrakan awalan hash), klien harus mengirim awalan hash ke server Web Risk untuk verifikasi. Server akan menampilkan semua hash SHA 256 lengkap yang berisi awalan hash tertentu. Jika salah satu hash panjang tersebut cocok dengan hash panjang URL yang dimaksud, maka URL tersebut dianggap tidak aman. Jika tidak ada hash panjang penuh yang cocok dengan hash panjang penuh URL yang dipermasalahkan, maka URL tersebut dianggap aman.

Google tidak pernah mengetahui URL yang Anda periksa. Google memang mempelajari awalan hash URL, tetapi awalan hash tidak memberikan banyak informasi tentang URL sebenarnya.

Untuk memeriksa apakah URL ada dalam daftar Web Risk, kirim permintaan HTTP GET ke metode hashes.search:

  • Permintaan HTTP GET mencakup awalan hash URL yang akan diperiksa.
  • Respons HTTP GET menampilkan hash panjang penuh yang cocok beserta waktu habis berlaku positif dan negatif.

Contoh: hashes.search

Permintaan HTTP GET

Dalam contoh berikut, nama dua daftar Web Risk dan awalan hash dikirim untuk perbandingan dan verifikasi. Untuk mengetahui detail selengkapnya, lihat parameter kueri hashes.search dan penjelasan yang mengikuti contoh kode.

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

Daftar Web Risk

Kolom threatTypes mengidentifikasi daftar Web Risk. Dalam contoh, dua daftar diidentifikasi: MALWARE dan SOCIAL_ENGINEERING.

Awalan hash ancaman

Kolom hashPrefix berisi awalan hash URL yang ingin Anda periksa. Kolom ini harus berisi awalan hash persis yang ada di database lokal. Misalnya, jika awalan hash lokal memiliki panjang 4 byte, maka kolom hashPrefix harus memiliki panjang 4 byte. Jika awalan hash lokal diperpanjang menjadi 7 byte, kolom hashPrefix harus memiliki panjang 7 byte.

Respons HTTP GET

Dalam contoh berikut, respons menampilkan ancaman yang cocok, yang berisi daftar Web Risk yang cocok, beserta waktu berakhirnya.

Isi respons

Isi respons mencakup informasi kecocokan (nama daftar dan hash panjang penuh serta durasi cache). Untuk mengetahui detail selengkapnya, lihat isi respons hashes.search dan penjelasan yang mengikuti contoh kode.

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

Mencocokkan dengan

Kolom threats menampilkan hash panjang penuh yang cocok untuk awalan hash. URL yang sesuai dengan hash ini dianggap tidak aman. Jika tidak ada kecocokan yang ditemukan untuk awalan hash, tidak ada yang ditampilkan; URL yang sesuai dengan awalan hash tersebut dianggap aman.

Masa berlaku

Kolom expireTime dan negativeExpireTime menunjukkan hingga kapan hash harus dianggap tidak aman atau aman. Untuk mengetahui detail selengkapnya, lihat Caching.