// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package google.cloud.webrisk.v1; import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/longrunning/operations.proto"; import "google/protobuf/timestamp.proto"; option csharp_namespace = "Google.Cloud.WebRisk.V1"; option go_package = "cloud.google.com/go/webrisk/apiv1/webriskpb;webriskpb"; option java_multiple_files = true; option java_outer_classname = "WebRiskProto"; option java_package = "com.google.webrisk.v1"; option objc_class_prefix = "GCWR"; option php_namespace = "Google\\Cloud\\WebRisk\\V1"; option ruby_package = "Google::Cloud::WebRisk::V1"; // Web Risk API defines an interface to detect malicious URLs on your // website and in client applications. service WebRiskService { option (google.api.default_host) = "webrisk.googleapis.com"; option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; // 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. rpc ComputeThreatListDiff(ComputeThreatListDiffRequest) returns (ComputeThreatListDiffResponse) { option (google.api.http) = { get: "/v1/threatLists:computeDiff" }; option (google.api.method_signature) = "threat_type,version_token,constraints"; } // This method is used to check whether a URI is on a given threatList. // Multiple threatLists may be searched in a single query. // The response will list all requested threatLists the URI was found to // match. If the URI is not found on any of the requested ThreatList an // empty response will be returned. rpc SearchUris(SearchUrisRequest) returns (SearchUrisResponse) { option (google.api.http) = { get: "/v1/uris:search" }; option (google.api.method_signature) = "uri,threat_types"; } // 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. rpc SearchHashes(SearchHashesRequest) returns (SearchHashesResponse) { option (google.api.http) = { get: "/v1/hashes:search" }; option (google.api.method_signature) = "hash_prefix,threat_types"; } // Creates a Submission of a URI suspected of containing phishing content to // be reviewed. If the result verifies the existence of malicious phishing // content, the site will be added to the [Google's Social Engineering // lists](https://support.google.com/webmasters/answer/6350487/) in order to // protect users that could get exposed to this threat in the future. Only // allowlisted projects can use this method during Early Access. Please reach // out to Sales or your customer engineer to obtain access. rpc CreateSubmission(CreateSubmissionRequest) returns (Submission) { option (google.api.http) = { post: "/v1/{parent=projects/*}/submissions" body: "submission" }; option (google.api.method_signature) = "parent,submission"; } // Submits a URI suspected of containing malicious content to be reviewed. // Returns a google.longrunning.Operation which, once the review is complete, // is updated with its result. You can use the [Pub/Sub API] // (https://cloud.google.com/pubsub) to receive notifications for the returned // Operation. If the result verifies the existence of malicious content, the // site will be added to the [Google's Social Engineering lists] // (https://support.google.com/webmasters/answer/6350487/) in order to // protect users that could get exposed to this threat in the future. Only // allowlisted projects can use this method during Early Access. Please reach // out to Sales or your customer engineer to obtain access. rpc SubmitUri(SubmitUriRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{parent=projects/*}/uris:submit" body: "*" }; option (google.longrunning.operation_info) = { response_type: "Submission" metadata_type: "SubmitUriMetadata" }; } } // Describes an API diff request. message ComputeThreatListDiffRequest { // The constraints for this diff. message Constraints { // 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. int32 max_diff_entries = 1; // 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. int32 max_database_entries = 2; // The compression types supported by the client. repeated CompressionType supported_compressions = 3; } // Required. The threat list to update. Only a single ThreatType should be // specified per request. If you want to handle multiple ThreatTypes, you must // make one request per ThreatType. ThreatType threat_type = 1 [(google.api.field_behavior) = REQUIRED]; // The current version token of the client for the requested list (the // client version that was received from the last successful diff). // 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. bytes version_token = 2; // Required. The constraints associated with this request. Constraints constraints = 3 [(google.api.field_behavior) = REQUIRED]; } message ComputeThreatListDiffResponse { // The type of response sent to the client. enum ResponseType { // Unknown. RESPONSE_TYPE_UNSPECIFIED = 0; // Partial updates are applied to the client's existing local database. DIFF = 1; // Full updates resets the client's entire local database. This means // that either the client had no state, was seriously out-of-date, // or the client is believed to be corrupt. RESET = 2; } // The expected state of a client's local database. message Checksum { // The SHA256 hash of the client state; that is, of the sorted list of all // hashes present in the database. bytes sha256 = 1; } // The type of response. This may indicate that an action must be taken by the // client when the response is received. ResponseType response_type = 4; // A set of entries to add to a local threat type's list. ThreatEntryAdditions additions = 5; // A set of entries to remove from a local threat type's list. // This field may be empty. ThreatEntryRemovals removals = 6; // The new opaque client version token. This should be retained by the client // and passed into the next call of ComputeThreatListDiff as 'version_token'. // A separate version token should be stored and used for each threatList. bytes new_version_token = 7; // The expected SHA256 hash of the client state; that is, of the sorted list // of all hashes present in the database after applying the provided diff. // If the client state doesn't match the expected state, the client must // discard this diff and retry later. Checksum checksum = 8; // The soonest the client should wait before issuing any diff // request. Querying sooner is unlikely to produce a meaningful diff. // Waiting longer is acceptable considering the use case. // If this field is not set clients may update as soon as they want. google.protobuf.Timestamp recommended_next_diff = 2; } // Request to check URI entries against threatLists. message SearchUrisRequest { // Required. The URI to be checked for matches. string uri = 1 [(google.api.field_behavior) = REQUIRED]; // Required. The ThreatLists to search in. Multiple ThreatLists may be // specified. repeated ThreatType threat_types = 2 [(google.api.field_behavior) = REQUIRED]; } message SearchUrisResponse { // Contains threat information on a matching uri. message ThreatUri { // The ThreatList this threat belongs to. repeated ThreatType threat_types = 1; // The cache lifetime for the returned match. Clients must not cache this // response past this timestamp to avoid false positives. google.protobuf.Timestamp expire_time = 2; } // The threat list matches. This might be empty if the URI is on no list. ThreatUri threat = 1; } // Request to return full hashes matched by the provided hash prefixes. message SearchHashesRequest { // 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). bytes hash_prefix = 1; // Required. The ThreatLists to search in. Multiple ThreatLists may be // specified. repeated ThreatType threat_types = 2 [(google.api.field_behavior) = REQUIRED]; } message SearchHashesResponse { // Contains threat information on a matching hash. message ThreatHash { // The ThreatList this threat belongs to. // This must contain at least one entry. repeated ThreatType threat_types = 1; // A 32 byte SHA256 hash. This field is in binary format. For JSON // requests, hashes are base64-encoded. bytes hash = 2; // The cache lifetime for the returned match. Clients must not cache this // response past this timestamp to avoid false positives. google.protobuf.Timestamp expire_time = 3; } // The full hashes that matched the requested prefixes. // The hash will be populated in the key. repeated ThreatHash threats = 1; // For requested entities that did not match the threat list, how long to // cache the response until. google.protobuf.Timestamp negative_expire_time = 2; } // The type of threat. This maps directly to the threat list a threat may // belong to. enum ThreatType { // No entries should match this threat type. This threat type is unused. THREAT_TYPE_UNSPECIFIED = 0; // Malware targeting any platform. MALWARE = 1; // Social engineering targeting any platform. SOCIAL_ENGINEERING = 2; // Unwanted software targeting any platform. UNWANTED_SOFTWARE = 3; // A list of extended coverage social engineering URIs targeting any // platform. SOCIAL_ENGINEERING_EXTENDED_COVERAGE = 4; } // The ways in which threat entry sets can be compressed. enum CompressionType { // Unknown. COMPRESSION_TYPE_UNSPECIFIED = 0; // Raw, uncompressed data. RAW = 1; // Rice-Golomb encoded data. RICE = 2; } // Contains the set of entries to add to a local database. // May contain a combination of compressed and raw data in a single response. message ThreatEntryAdditions { // The raw SHA256-formatted entries. // Repeated to allow returning sets of hashes with different prefix sizes. repeated RawHashes raw_hashes = 1; // The encoded 4-byte prefixes of SHA256-formatted entries, using a // Golomb-Rice encoding. The hashes are converted to uint32, sorted in // ascending order, then delta encoded and stored as encoded_data. RiceDeltaEncoding rice_hashes = 2; } // Contains the set of entries to remove from a local database. message ThreatEntryRemovals { // The raw removal indices for a local list. RawIndices raw_indices = 1; // The encoded local, lexicographically-sorted list indices, using a // Golomb-Rice encoding. Used for sending compressed removal indices. The // removal indices (uint32) are sorted in ascending order, then delta encoded // and stored as encoded_data. RiceDeltaEncoding rice_indices = 2; } // A set of raw indices to remove from a local list. message RawIndices { // The indices to remove from a lexicographically-sorted local list. repeated int32 indices = 1; } // The uncompressed threat entries in hash format. // Hashes can be anywhere from 4 to 32 bytes in size. A large majority are 4 // bytes, but some hashes are lengthened if they collide with the hash of a // popular URI. // // Used for sending ThreatEntryAdditons to clients that do not support // compression, or when sending non-4-byte hashes to clients that do support // compression. message RawHashes { // The number of bytes for each prefix encoded below. This field can be // anywhere from 4 (shortest prefix) to 32 (full SHA256 hash). // In practice this is almost always 4, except in exceptional circumstances. int32 prefix_size = 1; // The hashes, in binary format, concatenated into one long string. Hashes are // sorted in lexicographic order. For JSON API users, hashes are // base64-encoded. bytes raw_hashes = 2; } // The Rice-Golomb encoded data. Used for sending compressed 4-byte hashes or // compressed removal indices. message RiceDeltaEncoding { // The offset of the first entry in the encoded data, or, if only a single // integer was encoded, that single integer's value. If the field is empty or // missing, assume zero. int64 first_value = 1; // The Golomb-Rice parameter, which is a number between 2 and 28. This field // is missing (that is, zero) if `num_entries` is zero. int32 rice_parameter = 2; // The number of entries that are delta encoded in the encoded data. If only a // single integer was encoded, this will be zero and the single value will be // stored in `first_value`. int32 entry_count = 3; // The encoded deltas that are encoded using the Golomb-Rice coder. bytes encoded_data = 4; } // Wraps a URI that might be displaying malicious content. message Submission { // Required. The URI that is being reported for malicious content to be // analyzed. string uri = 1 [(google.api.field_behavior) = REQUIRED]; // Output only. ThreatTypes found to be associated with the submitted URI // after reviewing it. This might be empty if the URI was not added to any // list. repeated ThreatType threat_types = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; } // Context about the submission including the type of abuse found on the URI and // supporting details. // option (google.api.message_visibility).restriction = "TRUSTED_TESTER"; message ThreatInfo { // The abuse type found on the URI. enum AbuseType { // Default. ABUSE_TYPE_UNSPECIFIED = 0; // The URI contains malware. MALWARE = 1; // The URI contains social engineering. SOCIAL_ENGINEERING = 2; // The URI contains unwanted software. UNWANTED_SOFTWARE = 3; } // Confidence that a URI is unsafe. message Confidence { // Enum representation of confidence. enum ConfidenceLevel { // Default. CONFIDENCE_LEVEL_UNSPECIFIED = 0; // Less than 60% confidence that the URI is unsafe. LOW = 1; // Between 60% and 80% confidence that the URI is unsafe. MEDIUM = 2; // Greater than 80% confidence that the URI is unsafe. HIGH = 3; } oneof value { // A decimal representation of confidence in the range of 0 // to 1 where 0 indicates no confidence and 1 indicates // complete confidence. float score = 1; // Enum representation of confidence. ConfidenceLevel level = 2; } } // Context about why the URI is unsafe. message ThreatJustification { // Labels that explain how the URI was classified. enum JustificationLabel { // Default. JUSTIFICATION_LABEL_UNSPECIFIED = 0; // The submitter manually verified that the submission is unsafe. MANUAL_VERIFICATION = 1; // The submitter received the submission from an end user. USER_REPORT = 2; // The submitter received the submission from an automated system. AUTOMATED_REPORT = 3; } // Labels associated with this URI that explain how it was classified. repeated JustificationLabel labels = 1; // Free-form context on why this URI is unsafe. repeated string comments = 2; } // The type of abuse. AbuseType abuse_type = 1; // Confidence that the URI is unsafe. Confidence threat_confidence = 2; // Context about why the URI is unsafe. ThreatJustification threat_justification = 3; } // Details about how the threat was discovered. message ThreatDiscovery { // Platform types. enum Platform { // Default. PLATFORM_UNSPECIFIED = 0; // General Android platform. ANDROID = 1; // General iOS platform. IOS = 2; // General macOS platform. MACOS = 3; // General Windows platform. WINDOWS = 4; } // Platform on which the threat was discovered. Platform platform = 1; // CLDR region code of the countries/regions the URI poses a threat ordered // from most impact to least impact. Example: "US" for United States. repeated string region_codes = 2; } // Request to send a potentially phishy URI to WebRisk. message CreateSubmissionRequest { // Required. The name of the project that is making the submission. This // string is in the format "projects/{project_number}". string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "cloudresourcemanager.googleapis.com/Project" } ]; // Required. The submission that contains the content of the phishing report. Submission submission = 2 [(google.api.field_behavior) = REQUIRED]; } // Request to send a potentially malicious URI to WebRisk. message SubmitUriRequest { // Required. The name of the project that is making the submission. This // string is in the format "projects/{project_number}". string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "cloudresourcemanager.googleapis.com/Project" } ]; // Required. The submission that contains the URI to be scanned. Submission submission = 2 [(google.api.field_behavior) = REQUIRED]; // Provides additional information about the submission. ThreatInfo threat_info = 3; // Provides additional information about how the submission was discovered. ThreatDiscovery threat_discovery = 4; } // Metadata for the Submit URI long-running operation. // option (google.api.message_visibility).restriction = "TRUSTED_TESTER"; message SubmitUriMetadata { // Enum that represents the state of the long-running operation. enum State { // Default unspecified state. STATE_UNSPECIFIED = 0; // The operation is currently running. RUNNING = 1; // The operation finished with a success status. SUCCEEDED = 2; // The operation was cancelled. CANCELLED = 3; // The operation finished with a failure status. FAILED = 4; // The operation was closed with no action taken. CLOSED = 5; } // The state of the operation. State state = 1; // Creation time of the operation. google.protobuf.Timestamp create_time = 2; // Latest update time of the operation. google.protobuf.Timestamp update_time = 3; }