summaryrefslogtreecommitdiff
path: root/chromium/components/safe_browsing/core/common/proto/csd.proto
blob: e2339cee173ea89efb533c9111b22e11c500b681 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This proto file includes:
// (1) Client side phishing and malware detection request and response
//   protocol buffers.  Those protocol messages should be kept in sync
//   with the server implementation.
//
// (2) Safe Browsing reporting protocol buffers.
//   A ClientSafeBrowsingReportRequest is sent when a user opts-in to
//   sending detailed threat reports from the safe browsing interstitial page.
//   It is a list of Resource messages, which may contain the url of a
//   resource such as the page in the address bar or any other resource
//   that was loaded for this page.
//   In addition to the url, a resource can contain HTTP request and response
//   headers and bodies.
//
// If you want to change this protocol definition or you have questions
// regarding its format please contact chrome-anti-phishing@googlegroups.com.

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

package safe_browsing;

// Protocol buffer describing the Chrome user population of the user reporting
// data.
message ChromeUserPopulation {
  enum UserPopulation {
    UNKNOWN_USER_POPULATION = 0;
    SAFE_BROWSING = 1;  // Equivalent to standard protection.
    EXTENDED_REPORTING = 2;
    ENHANCED_PROTECTION = 3;
  }
  optional UserPopulation user_population = 1;

  // If user enabled history sync.
  optional bool is_history_sync_enabled = 2;

  // The finch active groups this user belongs to (if any). Active group is
  // defined by finch trial name and group name. Trial name and group name are
  // concatenated with separator "|", e.g. "PingOnlyTrial|DefaultGroup".
  repeated string finch_active_groups = 4;

  // Whether and how the current Chrome profile is being managed.
  enum ProfileManagementStatus {
    // Value not set.
    UNKNOWN = 0;

    // Profile management status is unavailable.
    UNAVAILABLE = 1;

    // The profile is not managed.
    NOT_MANAGED = 2;

    // Chrome is being managed by enterprise policies.
    ENTERPRISE_MANAGED = 3;
  }
  optional ProfileManagementStatus profile_management_status = 5
      [default = UNKNOWN];

  // Indicates if user opted in advanced protection program.
  optional bool is_under_advanced_protection = 6;

  // Indicates if user is in incognito mode.
  optional bool is_incognito = 7;

  // If the user is opted in to MBB.
  optional bool is_mbb_enabled = 8;

  // The simplified user agent string (e.g. Chrome/xy.0.abcd.e/Windows).
  optional string user_agent = 9;

  // The total number of profiles available on this machine. Some of these may
  // not be fully initialized so can't be used.
  optional int32 number_of_profiles = 10;

  // The number of created and fully initialized profiles. Some of these
  // profiles may be inactive.
  optional int32 number_of_loaded_profiles = 11;

  // The number of profiles that are currently open, i.e. have open browsers or
  // were open the last time Chrome was running. Profiles that fail to
  // initialize are skipped.
  optional int32 number_of_open_profiles = 12;

  // Server-side only field.
  reserved 13;

  // Tokens to connect different requests on the same page, used for measuring
  // the performance of Safe Browsing protections. If two requests have the
  // same token, it means they are from the same user visiting the same page.
  // See go/chrome-sb-pageload-tokens.
  message PageLoadToken {
    // The source that generates the token.
    enum TokenSource {
      SOURCE_UNSPECIFIED = 0;
      // The token is randomly generated on the client-side. It is 32 bytes long.
      CLIENT_GENERATION = 1;
    }
    optional TokenSource token_source = 1;
    // The timestamp when the token is generated or received.
    optional int64 token_time_msec = 2;
    // The value of the token.
    optional bytes token_value = 3;
  }
  // Note: This field is set as repeated to support tokens from multiple
  // sources.
  repeated PageLoadToken page_load_tokens = 14;
}

message ClientPhishingRequest {
  // URL that the client visited.  The CGI parameters are stripped by the
  // client.
  optional string url = 1;

  // A 5-byte SHA-256 hash prefix of the URL.  Before hashing the URL is
  // canonicalized, converted to a suffix-prefix expression and broadened
  // (www prefix is removed and everything past the last '/' is stripped).
  //
  // Marked OBSOLETE because the URL is sent for all users, making the hash
  // prefix unnecessary.
  optional bytes OBSOLETE_hash_prefix = 10;

  // Score that was computed on the client.  Value is between 0.0 and 1.0.
  // The larger the value the more likely the url is phishing.
  required float client_score = 2;

  // Note: we're skipping tag 3 because it was previously used.

  // Is true if the features for this URL were classified as phishing.
  // Currently, this will always be true for all client-phishing requests
  // that are sent to the server.
  optional bool is_phishing = 4;

  message Feature {
    // Feature name.  E.g., 'PageHasForms'.
    required string name = 1;

    // Feature value is always in the range [0.0, 1.0].  Boolean features
    // have value 1.0.
    required double value = 2;
  }

  // List of features that were extracted.  Those are the features that were
  // sent to the scorer and which resulted in client_score being computed.
  repeated Feature feature_map = 5;

  // The version number of the model that was used to compute the client-score.
  // Copied from ClientSideModel.version().
  optional int32 model_version = 6;

  // Field 7 is only used on the server.
  reserved 7;

  // List of features that are extracted in the client but are not used in the
  // machine learning model.
  repeated Feature non_model_feature_map = 8;

  // The referrer URL.  This field might not be set, for example, in the case
  // where the referrer uses HTTPs.
  // OBSOLETE: Use feature 'Referrer=<referrer>' instead.
  optional string OBSOLETE_referrer_url = 9;

  // Field 11 is only used on the server.
  reserved 11;

  // List of shingle hashes we extracted.
  repeated uint32 shingle_hashes = 12 [packed = true];

  // The model filename (basename) that was used by the client. Deprecated.
  optional string DEPRECATED_model_filename = 13 [deprecated = true];

  // Population that the reporting user is part of.
  optional ChromeUserPopulation population = 14;

  // Server-side only fields.
  reserved 15;
  reserved 16;

  // Basic visual information of the URL.
  // This section will be filled for SBER users only.
  optional bytes screenshot_digest = 17;
  optional bytes screenshot_phash = 18;
  optional int32 phash_dimension_size = 19;

  // The visual feature match results.
  // Allow multiple results if there are more than one matched target.
  repeated VisionMatchResult vision_match = 20;

  // Indicates whether the request is due to a match on the DOM features.
  optional bool is_dom_match = 21;

  // If we can find the complete referrer chain, this field will contains URLs
  // transitions from landing referrer to event in reverse chronological
  // order, i.e. event url comes first in this list, and landing referrer
  // comes last.
  // For Enhanced Protection users, if the referrer
  // chain is empty or partially missing, we will add/append recent navigation
  // events to this list. The type of these entries will be RECENT_NAVIGATION.
  repeated ReferrerChainEntry referrer_chain = 22;

  // The version of the TFLite model used for classification
  optional int32 tflite_model_version = 23;

  message CategoryScore {
    optional string label = 1;
    optional float value = 2;
  }
  // The resulting score from the TFLite model
  repeated CategoryScore tflite_model_scores = 24;

  // Whether the TFLite model believed the page was phishy.
  optional bool is_tflite_match = 25;

  // next available tag number: 26.
}

// Vision match result for one target image.
message VisionMatchResult {
  optional bytes matched_target_digest = 1;
  optional double vision_matched_phash_score = 2;
  optional double vision_matched_emd_score = 3;
}

message ClientPhishingResponse {
  required bool phishy = 1;

  // A list of SafeBrowsing host-suffix / path-prefix expressions that
  // are whitelisted.  The client must match the current top-level URL
  // against these whitelisted expressions and only apply a positive
  // phishing verdict above if the URL does not match any expression
  // on this whitelist.  The client must not cache these whitelisted
  // expressions.  This whitelist will be empty for the vast majority
  // of the responses but might contain up to 100 entries in emergency
  // situations.
  //
  // Marked OBSOLETE because the URL is sent for all users, so the server
  // can do whitelist matching.
  repeated string OBSOLETE_whitelist_expression = 2;
}

// The message is used for client request to determine whether the provided URL
// is safe for the purposes of entering user credentials for logging in.
message LoginReputationClientRequest {
  // The top level frame URL of the webpage that hosts the login form.
  optional string page_url = 1;

  // Type for the request.
  // It could be low reputation request or password reuse request.
  enum TriggerType {
    TRIGGER_TYPE_UNSPECIFIED = 0;
    UNFAMILIAR_LOGIN_PAGE = 1;
    PASSWORD_REUSE_EVENT = 2;
  }
  optional TriggerType trigger_type = 2;

  // The message contains features which can describe a frame. A frame can be
  // a top level web page or an iframe.
  message Frame {
    // Id of a frame. The frame whose index = 0 is the top level web page.
    optional int32 frame_index = 1;

    // Id of the parent frame.
    optional int32 parent_frame_index = 2;

    // Url of the frame. If could be top level url (from web page) or url of
    // the iframe.
    optional string url = 3;

    // Whether the frame contains password field.
    optional bool has_password_field = 4;

    // If we can find the complete referrer chain, this field will contains URLs
    // transitions from landing referrer to event in reverse chronological
    // order, i.e. event url comes first in this list, and landing referrer
    // comes last.
    // For Safe Browsing Extended Reporting, if the referrer
    // chain is empty or partially missing, we will add/append recent navigation
    // events to this list. The type of these entries will be RECENT_NAVIGATION.
    repeated ReferrerChainEntry referrer_chain = 5;

    // Options and metadata about the above referrer chain.
    optional ReferrerChainOptions referrer_chain_options = 7;

    // The message contains features of a form.
    message Form {
      // Action url of the form.
      optional string action_url = 1;

      // Whether the form contains password field.
      optional bool has_password_field = 2;
    }

    repeated Form forms = 6;

    // next available tag number: 8.
  }

  repeated Frame frames = 3;

  // The message contains fields needed for a password reuse event.
  // Next tag: 4
  message PasswordReuseEvent {
    // Domains from the Chrome password manager DB that are associated with
    // the same password as the one triggering this event. The field is filled
    // in only when TriggerType is PASSWORD_REUSE_EVENT, and only for users
    // opted in to extended reporting.
    repeated string domains_matching_password = 1;

    // The frame that the password reuse is detected.
    optional int32 frame_id = 2;

    // TODO(crbug/914410): Remove once ReusedPasswordAccountType is implemented.
    // Whether the reused password is used for Chrome signin.
    optional bool is_chrome_signin_password = 3;

    // TODO(crbug/914410): Remove once ReusedPasswordAccountType is implemented.
    // Sync account type. Only set if |is_chrome_signin_password| is true.
    enum SyncAccountType {
      // Not a sign-in user.
      NOT_SIGNED_IN = 0;

      // User signed in with @gmail.com, or @googlemail.com account.
      GMAIL = 1;

      // User signed in with a G Suite account.
      GSUITE = 2;
    }
    optional SyncAccountType sync_account_type = 4;

    // TODO(crbug/914410): Remove once ReusedPasswordAccountType is implemented.
    // Type of password being reused.
    enum ReusedPasswordType {
      REUSED_PASSWORD_TYPE_UNKNOWN = 0;

      // Password saved in Chrome's password manager.
      SAVED_PASSWORD = 1;

      // Password used in Chrome sign-in.
      SIGN_IN_PASSWORD = 2;

      // Other Gaia password used in Chrome's content area other than Chrome's
      // sign-in password.
      OTHER_GAIA_PASSWORD = 3;

      // Non-Gaia enterprise password captured from enterprise login page.
      ENTERPRISE_PASSWORD = 4;
    }
    optional ReusedPasswordType reused_password_type = 5
        [default = REUSED_PASSWORD_TYPE_UNKNOWN];

    message ReusedPasswordAccountType {
      // Whether the current reused password account is syncing.
      optional bool is_account_syncing = 1;

      enum AccountType {
        // User reused a password that is not a signed-in account, saved
        // password, or a non-GAIA enterprise account.
        UNKNOWN = 0;

        // User signed in with a dasher account.
        GSUITE = 1;

        // User signed in with @gmail.com, or @googlemail.com account.
        GMAIL = 2;

        // Password used for Enterprise login on an Enterprise login page.
        NON_GAIA_ENTERPRISE = 3;

        // Password saved in Chrome's password manager.
        SAVED_PASSWORD = 4;
      }
      optional AccountType account_type = 2;
    }

    optional ReusedPasswordAccountType reused_password_account_type = 6;
  }

  optional PasswordReuseEvent password_reuse_event = 4;

  // The number of verdicts stored on the client.
  optional int32 stored_verdict_cnt = 5;

  // Chrome user population.
  optional ChromeUserPopulation population = 6;

  // If user clicked through safe browsing interstitial on this page.
  optional bool clicked_through_interstitial = 7;

  // The MIME type of the page, e.g. "application/pdf".
  optional string content_type = 8;

  // Content area height in DIPs. This field should only be filled for extended
  // reporting users.
  optional int32 content_area_height = 9;

  // Content area width in DIPs. This field should only be filled for extended
  // reporting users.
  optional int32 content_area_width = 10;

  // Visual features of the current page. This field should only be filled for
  // extended reporting users.
  optional VisualFeatures visual_features = 11;

  // DOM features of the current page.
  optional DomFeatures dom_features = 12;

  enum ReportType {
    UNKNOWN = 0;
    // Normal/full ping to Safe Browsing containing all the fields in the
    // PasswordProtectionRequest.
    FULL_REPORT = 1;
    // Sample ping to Safe Browsing containing only the stripped URL and
    // referrer chain.
    SAMPLE_REPORT = 2;
  }
  // Whether the ping sent to Safe Browsing is a normal (full request) ping or a
  // sample ping for URLs on the allow-list.
  optional ReportType report_type = 13;

  // Information about Simplified URL display experiments in Chrome.
  // See go/phishguard-ping-spoof-detection
  message UrlDisplayExperiment {
    // True if SafeBrowsingDelayedWarnings is enabled.
    optional bool delayed_warnings_enabled = 1;
    // True if the "mouse" parameter of SafeBrowsingDelayedWarnings is enabled.
    optional bool delayed_warnings_mouse_clicks_enabled = 2;

    // True if RevealSteadyStateUrlPathQueryAndRefOnHover is enabled.
    optional bool reveal_on_hover = 3;
    // True if HideSteadyStateUrlPathQueryAndRefOnInteraction is enabled.
    optional bool hide_on_interaction = 4;
    // True if OmniboxUIExperimentElideToRegistrableDomain is enabled.
    optional bool elide_to_registrable_domain = 5;
    // True if this is the control group. This sent by the finch config.
    optional bool simplified_url_display_enabled = 6;
  };
  optional UrlDisplayExperiment url_display_experiment = 14;

  // The referring app info that launches Chrome. Only used on Android.
  // This information may be spoofed so do not rely solely on its correctness
  // for anti-abuse purposes. For more details, see:
  // go/phishguard-referring-app-android.
  message ReferringAppInfo {
    // The source of the referring_app_name.
    enum ReferringAppSource {
      REFERRING_APP_SOURCE_UNSPECIFIED = 0;
      // The referring app is known to Chrome. If the referring app info is from
      // this source, the referring_app_name is a hardcoded string that is
      // predefined in Chrome.
      KNOWN_APP_ID = 1;
      // The referring app is unknown to Chrome. The referring app name is
      // obtained from
      // https://developer.android.com/reference/android/provider/Browser?hl=en#EXTRA_APPLICATION_ID.
      // If the referring app info is from this source, the referring_app_name
      // is volatile and can be changed by the referring app.
      UNKNOWN_APP_ID = 2;
      // The referring app info is obtained from
      // https://developer.android.com/reference/android/app/Activity#getReferrer().
      // If the referring app info is from this source, the referring_app_name
      // is volatile and can be changed by the referring app.
      ACTIVITY_REFERRER = 3;
    }

    optional ReferringAppSource referring_app_source = 1;

    optional string referring_app_name = 2;
  }

  optional ReferringAppInfo referring_app_info = 15;
}

// The message is used for client response for login reputation requests.
message LoginReputationClientResponse {
  // Type of verdicts issued by the server.
  enum VerdictType {
    VERDICT_TYPE_UNSPECIFIED = 0;
    // No warning will be displayed.
    SAFE = 1;
    // The site has low reputation or low popularity.
    LOW_REPUTATION = 2;
    // The url matches with blocklist entries.
    PHISHING = 3;
  }
  optional VerdictType verdict_type = 1;

  // TTL of the verdict in seconds.
  optional int64 cache_duration_sec = 2;

  // A host-suffix/path-prefix expression which defines a collections of pages
  // with common ownership from the same domain.
  // Generally, the pattern is defined on the granularity of domains.
  // For domains managed by multiple parties, especially in the case of large
  // hosting sites (e.g., geocities.com), we further divide the domains.
  //
  // Examples:
  //    www.google.com/foo/bar?param=val -> google.com
  //    www.geocities.com/foo/bar.html -> geocities.com/foo
  //    adwords.blogspot.com/index.html -> adwords.blogspot.com
  //
  // The pattern will always match the page_url of the request, and will be
  // a substring of page_url.
  optional string cache_expression = 3;

  // Deprecated.
  optional bool DEPRECATED_cache_expression_exact_match = 4 [deprecated = true];

  // A token unique to each request which correlates response and post-warning
  // actions.
  optional bytes verdict_token = 5;
}

// This message encapsulates all the visual features of the current page.
message VisualFeatures {
  // One bin in a color histogram.
  message ColorHistogramBin {
    // The average x-coordinate of the pixels in this bin.
    optional float centroid_x = 1;

    // The average y-coordinate of the pixels in this bin.
    optional float centroid_y = 2;

    // The quantized R-value for this bin.
    optional int32 quantized_r = 3;

    // The quantized G-value for this bin.
    optional int32 quantized_g = 4;

    // The quantized B-value for this bin.
    optional int32 quantized_b = 5;

    // The normalized weight of this bin.
    optional float weight = 6;
  }

  // Represents the color histogram of a login page.
  message ColorHistogram { repeated ColorHistogramBin bins = 1; }

  // Color histogram of the current page.
  optional ColorHistogram color_histogram = 1;

  // Represents the blurred, downsampled image of the login page.
  message BlurredImage {
    // The width of the image.
    optional int32 width = 1;

    // The height of the image.
    optional int32 height = 2;

    // The image data, stored in RGB order. This will have length
    // 3*width*height. The bytes are stored in row-major order, starting from
    // the top most row.
    optional bytes data = 3;
  }

  // Blurred, downsampled image of the current page.
  // Using Rec 2020 color space:
  // https://en.wikipedia.org/wiki/Rec._2020
  optional BlurredImage image = 2;
}

// This message encapsulates all the DOM features of the current page.
message DomFeatures {
  message Feature {
    // Feature name. E.g., 'PageHasForms'
    optional string name = 1;

    // Feature value is always in the range [0.0, 1.0].  Boolean features
    // have value 1.0.
    optional double value = 2;
  }

  // List of features extracted.
  repeated Feature feature_map = 1;

  // List of shingle hashes we extracted.
  repeated uint32 shingle_hashes = 2 [packed = true];

  // The model version used to generate these hashes. This is copied from
  // ClientSideModel.version(). The model sets the term list, which affects
  // the feature extraction.
  optional int32 model_version = 3;
}

message ClientDownloadRequest {
  // The final URL of the download (after all redirects).
  required string url = 1;

  // This message contains various binary digests of the download payload.
  message Digests {
    optional bytes sha256 = 1;
    optional bytes sha1 = 2;
    optional bytes md5 = 3;
  }
  required Digests digests = 2;

  // This is the length in bytes of the download payload.
  required int64 length = 3;

  // Type of the resources stored below.
  enum ResourceType {
    // The final URL of the download payload.  The resource URL should
    // correspond to the URL field above.
    DOWNLOAD_URL = 0;
    // A redirect URL that was fetched before hitting the final DOWNLOAD_URL.
    DOWNLOAD_REDIRECT = 1;
    // The final top-level URL of the tab that triggered the download.
    TAB_URL = 2;
    // A redirect URL thas was fetched before hitting the final TAB_URL.
    TAB_REDIRECT = 3;
    // The document URL for a PPAPI plugin instance that initiated the download.
    // This is the document.url for the container element for the plugin
    // instance.
    PPAPI_DOCUMENT = 4;
    // The plugin URL for a PPAPI plugin instance that initiated the download.
    PPAPI_PLUGIN = 5;
  }

  message Resource {
    required string url = 1;
    required ResourceType type = 2;
    optional bytes remote_ip = 3;
    // This will only be set if the referrer is available and if the
    // resource type is either TAB_URL or DOWNLOAD_URL.
    optional string referrer = 4;

    // TODO(noelutz): add the transition type?
  }

  // This repeated field will store all the redirects as well as the
  // final URLs for the top-level tab URL (i.e., the URL that
  // triggered the download) as well as for the download URL itself.
  repeated Resource resources = 4;

  // A trust chain of certificates.  Each chain begins with the signing
  // certificate of the binary, and ends with a self-signed certificate,
  // typically from a trusted root CA.  This structure is analogous to
  // CERT_CHAIN_CONTEXT on Windows.
  message CertificateChain {
    // A single link in the chain.
    message Element {
      // DER-encoded X.509 representation of the certificate.
      optional bytes certificate = 1;
      // Fields 2 - 7 are only used on the server.
      reserved 2 to 7;
    }
    repeated Element element = 1;
  }

  // This is an OS X only message to report extended attribute informations.
  // Extended attributes on OS X are used for various security mechanisms,
  // which makes them interesting to Chrome.
  message ExtendedAttr {
    // This is the name of the extended attribute.
    required string key = 1;
    // This is the value of the extended attribute.
    optional bytes value = 2;
  }

  message SignatureInfo {
    // All certificate chains for each of the binary's signers.  Multiple chains
    // may be present if the binary or any certificate has multiple signers.
    // Absence of certificate chains does not imply that the binary is not
    // signed (in that case, SignedData blobs extracted from the binary may be
    // preset), but does mean that trust has not been verified.
    repeated CertificateChain certificate_chain = 1;

    // True if the signature was trusted on the client.
    optional bool trusted = 2;

    // On Windows, PKCS#7 SignedData blobs extracted from a portable executable
    // image's attribute certificate table. The presence of these does not imply
    // that the signatures were deemed trusted by the client.
    // On Mac, this is the code signature blob referenced by the
    // LC_CODE_SIGNATURE load command.
    repeated bytes signed_data = 3;

    // On OS X, code signing data can be contained in the extended attributes of
    // a file. As Gatekeeper respects this signature, we look for it and collect
    // it.
    repeated ExtendedAttr xattr = 4;
  }

  // This field will only be set if the binary is signed.
  optional SignatureInfo signature = 5;

  // True if the download was user initiated.
  optional bool user_initiated = 6;

  // Fields 7 and 8 are only used on the server.
  reserved 7, 8;

  // Name of the file where the download would be stored if the
  // download completes.  E.g., "bla.exe".
  optional string file_basename = 9;

  // Starting with Chrome M19 we're also sending back pings for Chrome
  // extensions that get downloaded by users.
  enum DownloadType {
    WIN_EXECUTABLE = 0;    // Currently all .exe, .cab and .msi files.
    CHROME_EXTENSION = 1;  // .crx files.
    ANDROID_APK = 2;       // .apk files.
    // .zip files containing one of the other executable types.
    ZIPPED_EXECUTABLE = 3;
    MAC_EXECUTABLE = 4;  // .dmg, .pkg, etc.
    ZIPPED_ARCHIVE = 5;  // .zip file containing another archive.
    ARCHIVE = 6;         // Archive that doesn't have a specific DownloadType.
    // A .zip that Chrome failed to unpack to the point of finding exe/zips.
    INVALID_ZIP = 7;
    // A .dmg, .pkg, etc, that Chrome failed to unpack to the point of finding
    // Mach O's.
    MAC_ARCHIVE_FAILED_PARSING = 8;
    // A download request initiated via PPAPI. Typically the requestor is
    // a Flash applet.
    PPAPI_SAVE_REQUEST = 9;
    // A file we don't support, but we've decided to sample and send
    // a light-ping.
    SAMPLED_UNSUPPORTED_FILE = 10;
    // .rar file containing one of the other executable types.
    RAR_COMPRESSED_EXECUTABLE = 11;
    // .rar file containing another archive.
    RAR_COMPRESSED_ARCHIVE = 12;
    // .rar file that Chrome failed to unpack to the point of finding
    // executables or archives.
    INVALID_RAR = 13;
    // Office Document or PDF.
    DOCUMENT = 14;
  }
  optional DownloadType download_type = 10 [default = WIN_EXECUTABLE];

  // Locale of the device, eg en, en_US.
  optional string locale = 11;

  message PEImageHeaders {
    // IMAGE_DOS_HEADER.
    optional bytes dos_header = 1;
    // IMAGE_FILE_HEADER.
    optional bytes file_header = 2;
    // IMAGE_OPTIONAL_HEADER32. Present only for 32-bit PE images.
    optional bytes optional_headers32 = 3;
    // IMAGE_OPTIONAL_HEADER64. Present only for 64-bit PE images.
    optional bytes optional_headers64 = 4;
    // IMAGE_SECTION_HEADER.
    repeated bytes section_header = 5;
    // Contents of the .edata section.
    optional bytes export_section_data = 6;

    message DebugData {
      // IMAGE_DEBUG_DIRECTORY.
      optional bytes directory_entry = 1;
      optional bytes raw_data = 2;
    }

    repeated DebugData debug_data = 7;
  }

  message MachOHeaders {
    // The mach_header or mach_header_64 struct.
    required bytes mach_header = 1;

    message LoadCommand {
      // |command_id| is the first uint32 of |command| as well, but is
      // extracted for easier processing.
      required uint32 command_id = 1;
      // The entire data stream of the load command.
      required bytes command = 2;
    }

    // All the load commands of the Mach-O file.
    repeated LoadCommand load_commands = 2;
  }

  message ImageHeaders {
    // Windows Portable Executable image headers.
    optional PEImageHeaders pe_headers = 1;

    // OS X Mach-O image headers.
    repeated MachOHeaders mach_o_headers = 2;
  };

  // Fields 12-17 are reserved for server-side use and are never sent by the
  // client.
  reserved 12 to 17;

  optional ImageHeaders image_headers = 18;

  // Fields 19-21 are reserved for server-side use and are never sent by the
  // client.
  reserved 19 to 21;

  // A binary or archive contained in an archive (e.g., a .exe in a .zip
  // archive, or a .zip inside a .zip).
  message ArchivedBinary {
    optional string file_basename = 1;
    optional DownloadType download_type = 2;
    optional Digests digests = 3;
    optional int64 length = 4;
    optional SignatureInfo signature = 5;
    optional ImageHeaders image_headers = 6;

    // Indicates if the given file is password protected.
    optional bool is_encrypted = 7;

    // Only used on the client side, since filtering for executable files
    // happens after the utility process has finished analyzing the archive.
    optional bool is_executable = 8;
    optional bool is_archive = 9;
  }

  repeated ArchivedBinary archived_binary = 22;

  // Population that the reporting user is part of.
  optional ChromeUserPopulation population = 24;

  // True if the .zip or DMG, etc, was 100% successfully unpacked.
  optional bool archive_valid = 26;

  // True if this ClientDownloadRequest is from a whitelisted domain.
  optional bool skipped_url_whitelist = 28;

  // True if this ClientDownloadRequest contains a whitelisted certificate.
  optional bool skipped_certificate_whitelist = 31;

  // PPAPI_SAVE_REQUEST type messages may have more than one suggested filetype.
  // Each element in this collection indicates an alternate extension including
  // the leading extension separator.
  repeated string alternate_extensions = 35;

  // If we can find the complete referrer chain, this field will contains URLs
  // transitions from landing referrer to event in reverse chronological
  // order, i.e. event url comes first in this list, and landing referrer
  // comes last.
  // For Safe Browsing Extended Reporting, if the referrer chain
  // is empty or partially missing, we will add/append recent navigation events
  // to this list. The type of these entries will be RECENT_NAVIGATION.
  repeated ReferrerChainEntry referrer_chain = 36;

  // Options and metadata about the above referrer chain.
  optional ReferrerChainOptions referrer_chain_options = 50;

  // Deprecated.
  optional bool DEPRECATED_download_attribution_finch_enabled = 39
      [deprecated = true];

  // The Mac disk image code signature.
  // The underlying structure of code signature is defined at
  // https://opensource.apple.com/source/xnu/xnu-2782.1.97/bsd/sys/codesign.h
  optional bytes udif_code_signature = 40;

  // Mac-only. A detached code signature contains the DER-encoded PKCS7 data
  // of a codesigned artifact. Detached signatures are used for signing files
  // that are not Mach-O and thus cannot have a LC_CODE_SIGNATURE load command.
  message DetachedCodeSignature {
    required string file_name = 1;
    required bytes contents = 2;
  }
  repeated DetachedCodeSignature detached_code_signature = 59;

  // When this is set to true, we expect the server to provide heightened
  // protection for Advanced Protection users.
  optional bool request_ap_verdicts = 67;

  // For archives files the number of files and directories contained within the
  // archive.
  optional int32 archive_file_count = 68;
  optional int32 archive_directory_count = 69;

  // Only for display on chrome://safe-browsing. The actual token is sent in the
  // "Authorization: Bearer" header
  optional string access_token = 78;

  // next available tag number: 85;
  message DocumentInfo { optional bool contains_macros = 1; }

  message DocumentProcessingInfo {
    optional bool processing_successful = 1;
    // The high-level error type returned from MalDocA when it cannot
    // successfully process a document.
    enum MaldocaErrorType {
      // error codes for gRPC APIs
      OK = 0;
      CANCELLED = 1;
      UNKNOWN = 2;
      INVALID_ARGUMENT = 3;
      DEADLINE_EXCEEDED = 4;
      NOT_FOUND = 5;
      ALREADY_EXISTS = 6;
      PERMISSION_DENIED = 7;
      RESOURCE_EXHAUSTED = 8;
      FAILED_PRECONDITION = 9;
      ABORTED = 10;
      OUT_OF_RANGE = 11;
      UNIMPLEMENTED = 12;
      INTERNAL = 13;
      UNAVAILABLE = 14;
      DATA_LOSS = 15;
      UNAUTHENTICATED = 16;

      // MalDocA Error Codes
      // third_party/maldoca/src/maldoca/base/status_proto.proto
      DOC_TYPE_INFERENCE_FAILED = 1000;
      UNSUPPORTED_DOC_TYPE = 1001;
      SANDBOX_ERROR = 1002;
      ARCHIVE_CORRUPTED = 1003;
      OLE_DIR_PARSING_FAILED = 1004;
      OLE_FAT_HEADER_PARSING_FAILED = 1005;
      PREFIXED_ANSI_STRING_HEADER_TOO_SHORT = 1006;
      PREFIXED_ANSI_STRING_CONTENT_TOO_SHORT = 1007;
      CLIPBOARD_FORMAT_OR_ANSI_STRING_TOO_SHORT = 1008;
      BOF_HEADER_TOO_SHORT = 1009;
      NOT_BIFF_FORMAT = 1010;
      FAIL_PARSE_BIFF_VERSION = 1011;
      INVALID_DDE_OLE_LINK = 1012;
      OLE_NATIVE_EMBEDDED_PARSE_SIZE_FAIL = 1013;
      OLE_NATIVE_EMBEDDED_SIZE_MISMATCH = 1014;
      OLE_NATIVE_EMBEDDED_PARSE_TYPE_FAIL = 1015;
      OLE_NATIVE_EMBEDDED_PARSE_FILENAME_FAIL = 1016;
      OLE_NATIVE_EMBEDDED_PARSE_FILEPATH_FAIL = 1017;
      OLE_NATIVE_EMBEDDED_PARSE_RESERVED_FAIL = 1018;
      OLE_NATIVE_EMBEDDED_PARSE_TEMPPATH_FAIL = 1019;
      OLE_NATIVE_EMBEDDED_PARSE_FILESIZE_FAIL = 1020;
      OLE_NATIVE_EMBEDDED_FILESIZE_MISMATCH = 1021;
      OLE_NATIVE_EMBEDDED_PARSE_CONTENT_FAIL = 1022;
      INVALID_OLE2_HEADER = 1023;
      INVALID_FAT_HEADER = 1024;
      EMPTY_FAT_HEADER = 1025;
      INVALID_ROOT_DIR = 1026;
      MISSING_FILE_IN_ARCHIVE = 1027;
      INVALID_XML_DOC = 1028;
      MISSING_PROPERTIES = 1029;
      NOT_IMPLEMENTED_FOR_CHROME = 1030;
      NOT_IMPLEMENTED = 1031;
      MISSING_ENCODING = 1032;
    }
    optional MaldocaErrorType maldoca_error_type = 2;
    optional string maldoca_error_message = 3;
  }

  message DocumentSummary {
    optional DocumentInfo metadata = 1;
    optional DocumentProcessingInfo processing_info = 2;
  }

  optional DocumentSummary document_summary = 84;
}

message ReferrerChainOptions {
  // The number of recent navigations we'd like to collect. This number is
  // controlled by Finch parameter and its default value is 0.
  optional int32 recent_navigations_to_collect = 1 [default = 0];
}

// Please update SafeBrowsingNavigationObserverManager::SanitizeReferrerChain()
// if you're adding more fields to this message.
message ReferrerChainEntry {
  enum URLType {
    // URL of safe browsing events that are at the end of the referrer chain.
    // e.g. URL of a download, URL of a low reputation login page, etc.
    EVENT_URL = 1;  // e.g.

    // Landing page is the page user directly interacts with to trigger the
    // above event, e.g. the page where user clicks a download button.
    LANDING_PAGE = 2;

    // Landing referrer is the one user directly interacts with right before
    // navigating to the landing page.
    LANDING_REFERRER = 3;

    // Client redirect refers to committed navigation between landing page and
    // the targeted event, or between landing referrer page and landing page.
    // Client redirect is not triggered by user gesture.
    CLIENT_REDIRECT = 4;

    DEPRECATED_SERVER_REDIRECT = 5;  // Deprecated

    // For Safe Browsing Extended Reporting, if the referrer
    // chain is empty or partially missing, we will add/append recent navigation
    // events to this list. RECENT_NAVIGATION type is set for these cases.
    RECENT_NAVIGATION = 6;

    // The REFERRER type is used for entries that recede the LANDING_REFERRER in
    // the referrer chain, when more than two gestures are included in the
    // referrer chain.
    REFERRER = 7;
  }

  enum NavigationInitiation {
    // Convenient default value, should not be used in real ReferrerChainEntry.
    UNDEFINED = 0;

    // Navigation is initiated by the browser process. e.g. user enters url into
    // address bar, or user opens a bookmark. This isn't perfect reliable due to
    // some edge cases, such as forward/back navigation and opening a link from
    // context menu.
    BROWSER_INITIATED = 1;

    // Navigation is initiated by the renderer process and there is no user
    // gesture associate with this navigation. e.g.
    // * redirect via the <meta http-equiv="refresh"> tag
    // * change window.location.href
    RENDERER_INITIATED_WITHOUT_USER_GESTURE = 2;

    // Navigation is initiated by the renderer process and there is a clear user
    // gesture associate with this navigation. e.g.
    //  * <a> link click
    //  * using window.history.pushState (i.e. back, forward button interaction)
    RENDERER_INITIATED_WITH_USER_GESTURE = 3;
  }

  message ServerRedirect {
    // [required] server redirect url
    optional string url = 1;

    // Additional fields for future expansion.
  }

  // [required] The url of this Entry.
  optional string url = 1;

  // Only set if it is different from |url|.
  optional string main_frame_url = 9;

  // Type of URLs, such as event url, landing page, etc.
  optional URLType type = 2 [default = CLIENT_REDIRECT];

  // IP addresses corresponding to this host.
  repeated string ip_addresses = 3;

  // Referrer url of this entry.
  optional string referrer_url = 4;

  // Main frame URL of referrer.
  // Only set if it is different from |referrer_url|.
  optional string referrer_main_frame_url = 5;

  // If this URL loads in a different tab/frame from previous one.
  optional bool is_retargeting = 6;

  optional double navigation_time_msec = 7;

  // Set only if server redirects happened in navigation.
  // The first entry in |server_redirect_chain| should be the original request
  // url, and the last entry should be the same as |url|.
  repeated ServerRedirect server_redirect_chain = 8;

  // How this navigation is initiated.
  optional NavigationInitiation navigation_initiation = 10;

  // Whether we think this entry may have been launched by an external
  // application. This will have no false negatives, but some false positives
  // are possible.
  optional bool maybe_launched_by_external_application = 11;

  // Whether subframe URLs are removed due to user consent restriction.
  // When this field is set to true, |url| is set to
  // their relative mainframe URLs and |main_frame_url| is cleared.
  optional bool is_subframe_url_removed = 12;

  // Whether subframe referrer URLs are removed due to user consent restriction.
  // When this field is set to true, |referrer_url| is set to
  // their relative mainframe URLs and |referrer_main_frame_url| is cleared.
  optional bool is_subframe_referrer_url_removed = 13;

  // Whether any of the URLs in the |url|, |main_frame_url|, |referrer_url|,
  // |referrer_main_frame_url| fields are removed because the URL matches the
  // SafeBrowsingAllowlistDomains enterprise policy in Chrome, or the URL is
  // recorded before the user consent.
  optional bool is_url_removed_by_policy = 14;

  // next available tag number: 15.
}  // End of ReferrerChainEntry

message ClientDownloadResponse {
  enum Verdict {
    // Download is considered safe.
    SAFE = 0;
    // Download is considered dangerous.  Chrome should show a warning to the
    // user.
    DANGEROUS = 1;
    // Download is uncommon.  Chrome should display a less severe warning.
    UNCOMMON = 2;
    // The download is potentially unwanted.
    POTENTIALLY_UNWANTED = 3;
    // The download is from a dangerous host.
    DANGEROUS_HOST = 4;
    // The backend doesn't have confidence in its verdict of this file.
    // Chrome should show the default warning if configured for this file type.
    UNKNOWN = 5;
    // Download is associated with stealing cookies and account compromise.
    // Chrome should show a severe warning.
    DANGEROUS_ACCOUNT_COMPROMISE = 8;
  }
  optional Verdict verdict = 1 [default = SAFE];

  message MoreInfo {
    // A human-readable string describing the nature of the warning.
    // Only if verdict != SAFE. Localized based on request.locale.
    optional string description = 1;

    // A URL to get more information about this warning, if available.
    optional string url = 2;
  }
  optional MoreInfo more_info = 2;

  // An arbitrary token that should be sent along for further server requests.
  optional bytes token = 3;

  // Whether the server requests that this binary be uploaded.
  optional bool upload = 5;

  // Whether or not Chrome should prompt the user for deep scanning
  optional bool request_deep_scan = 19;
}

// The following protocol buffer holds the feedback report gathered
// from the user regarding the download.
message ClientDownloadReport {
  // The information of user who provided the feedback.
  // This is going to be useful for handling appeals.
  message UserInformation { optional string email = 1; }

  enum Reason {
    SHARE = 0;
    FALSE_POSITIVE = 1;
    APPEAL = 2;
  }

  // The type of feedback for this report.
  optional Reason reason = 1;

  // The original download ping
  optional ClientDownloadRequest download_request = 2;

  // Stores the information of the user who provided the feedback.
  optional UserInformation user_information = 3;

  // Unstructed comments provided by the user.
  optional bytes comment = 4;

  // The original download response sent from the verdict server.
  optional ClientDownloadResponse download_response = 5;
}

// This is used to send back upload status to the client after upload completion
message ClientUploadResponse {
  enum UploadStatus {
    // The upload was successful and a complete response can be expected
    SUCCESS = 0;

    // The upload was unsuccessful and the response is incomplete.
    UPLOAD_FAILURE = 1;
  }

  // Holds the upload status
  optional UploadStatus status = 1;

  // Holds the permalink where the results of scanning the binary are available
  optional string permalink = 2;
}

message ClientIncidentReport {
  message IncidentData {
    message TrackedPreferenceIncident {
      enum ValueState {
        UNKNOWN = 0;
        CLEARED = 1;
        WEAK_LEGACY_OBSOLETE = 2;
        CHANGED = 3;
        UNTRUSTED_UNKNOWN_VALUE = 4;
        BYPASS_CLEARED = 5;
        BYPASS_CHANGED = 6;
      }

      optional string path = 1;
      optional string atomic_value = 2;
      repeated string split_key = 3;
      optional ValueState value_state = 4;
    }

    message BinaryIntegrityIncident {
      optional string file_basename = 1;
      optional ClientDownloadRequest.SignatureInfo signature = 2;
      optional ClientDownloadRequest.ImageHeaders image_headers = 3;
      optional int32 sec_error = 4;

      message ContainedFile {
        optional string relative_path = 1;
        optional ClientDownloadRequest.SignatureInfo signature = 2;
        optional ClientDownloadRequest.ImageHeaders image_headers = 3;
      }
      repeated ContainedFile contained_file = 5;
    }

    message ResourceRequestIncident {
      enum Type {
        UNKNOWN = 0;
        TYPE_PATTERN = 3;
      }
      optional bytes digest = 1;
      optional string origin = 2;
      optional Type type = 3 [default = UNKNOWN];
    }

    optional int64 incident_time_msec = 1;
    optional TrackedPreferenceIncident tracked_preference = 2;
    optional BinaryIntegrityIncident binary_integrity = 3;
    // Note: skip tag 4,5,6 because they were previously used.
    reserved 4 to 6;
    optional ResourceRequestIncident resource_request = 7;
    // Note: skip tag 8 because it was previously used.
    reserved 8;
  }

  repeated IncidentData incident = 1;

  message DownloadDetails {
    optional bytes token = 1;
    optional ClientDownloadRequest download = 2;
    optional int64 download_time_msec = 3;
    optional int64 open_time_msec = 4;
  }

  optional DownloadDetails download = 2;

  message EnvironmentData {
    message OS {
      optional string os_name = 1;
      optional string os_version = 2;

      message RegistryValue {
        optional string name = 1;
        optional uint32 type = 2;
        optional bytes data = 3;
      }

      message RegistryKey {
        optional string name = 1;
        repeated RegistryValue value = 2;
        repeated RegistryKey key = 3;
      }

      repeated RegistryKey registry_key = 3;

      optional bool is_enrolled_to_domain = 4;
    }
    optional OS os = 1;
    message Machine {
      optional string cpu_architecture = 1;
      optional string cpu_vendor = 2;
      optional uint32 cpuid = 3;
    }
    optional Machine machine = 2;
    message Process {
      optional string version = 1;
      repeated string OBSOLETE_dlls = 2;
      message Patch {
        optional string function = 1;
        optional string target_dll = 2;
      }
      repeated Patch patches = 3;
      message NetworkProvider {}
      repeated NetworkProvider network_providers = 4;
      enum Channel {
        CHANNEL_UNKNOWN = 0;
        CHANNEL_CANARY = 1;
        CHANNEL_DEV = 2;
        CHANNEL_BETA = 3;
        CHANNEL_STABLE = 4;
      }
      optional Channel chrome_update_channel = 5;
      optional int64 uptime_msec = 6;
      optional bool metrics_consent = 7;
      // Obsolete: extended consent is now required for incident reporting.
      optional bool OBSOLETE_extended_consent = 8;
      message Dll {
        enum Feature {
          UNKNOWN = 0;
          LSP = 1;
        }
        optional string path = 1;
        optional uint64 base_address = 2;
        optional uint32 length = 3;
        repeated Feature feature = 4;
        optional ClientDownloadRequest.ImageHeaders image_headers = 5;
      }
      repeated Dll dll = 9;
      repeated string blocklisted_dll = 10;
      message ModuleState {
        enum ModifiedState {
          UNKNOWN = 0;
          MODULE_STATE_UNKNOWN = 1;
          MODULE_STATE_UNMODIFIED = 2;
          MODULE_STATE_MODIFIED = 3;
        }
        optional string name = 1;
        optional ModifiedState modified_state = 2;
        repeated string OBSOLETE_modified_export = 3;

        message Modification {
          optional uint32 file_offset = 1;
          optional int32 byte_count = 2;
          optional bytes modified_bytes = 3;
          optional string export_name = 4;
        }
        repeated Modification modification = 4;
      }
      repeated ModuleState module_state = 11;
      // Obsolete: field trials no longer enable incident reporting.
      optional bool OBSOLETE_field_trial_participant = 12;
    }
    optional Process process = 3;
  }

  message ExtensionData {
    message ExtensionInfo {
      enum ExtensionState {
        STATE_UNKNOWN = 0;
        STATE_ENABLED = 1;
        STATE_DISABLED = 2;
        STATE_BLOCKLISTED = 3;
        STATE_BLOCKED = 4;
        STATE_TERMINATED = 5;
      }

      optional string id = 1;
      optional string version = 2;
      optional string name = 3;
      optional string description = 4;
      optional ExtensionState state = 5 [default = STATE_UNKNOWN];
      optional int32 type = 6;
      optional string update_url = 7;
      optional bool has_signature_validation = 8;
      optional bool signature_is_valid = 9;
      optional bool installed_by_custodian = 10;
      optional bool installed_by_default = 11;
      optional bool installed_by_oem = 12;
      optional bool from_bookmark = 13;
      optional bool from_webstore = 14;
      optional bool converted_from_user_script = 15;
      optional bool may_be_untrusted = 16;
      optional int64 install_time_msec = 17;
      optional int32 manifest_location_type = 18;
      optional string manifest = 19;
    }

    optional ExtensionInfo last_installed_extension = 1;
  }

  optional EnvironmentData environment = 3;

  // Population that the reporting user is part of.
  optional ChromeUserPopulation population = 7;

  optional ExtensionData extension_data = 8;

  message NonBinaryDownloadDetails {
    optional string file_type = 1;
    optional bytes url_spec_sha256 = 2;
    optional string host = 3;
    optional int64 length = 4;
  }

  optional NonBinaryDownloadDetails non_binary_download = 9;
}

message ClientIncidentResponse {
  optional bytes token = 1;
  optional bool download_requested = 2;

  message EnvironmentRequest { optional int32 dll_index = 1; }

  repeated EnvironmentRequest environment_requests = 3;
}

message DownloadMetadata {
  optional uint32 download_id = 1;

  optional ClientIncidentReport.DownloadDetails download = 2;
}

// A Detailed Safebrowsing Report from clients. Chrome safebrowsing reports are
// only sent by Chrome users who have opted into extended Safe Browsing.
// This proto is replacing ClientMalwareReportRequest.
// Next tag: 27
message ClientSafeBrowsingReportRequest {
  // Note: A lot of the "optional" fields would make sense to be
  // "required" instead.  However, having them as optional allows the
  // clients to send "stripped down" versions of the message in the
  // future, if we want to.

  enum ReportType {
    UNKNOWN = 0;
    URL_PHISHING = 1;
    URL_MALWARE = 2;
    URL_UNWANTED = 3;
    URL_CLIENT_SIDE_PHISHING = 4;
    URL_CLIENT_SIDE_MALWARE = 5;
    DANGEROUS_DOWNLOAD_RECOVERY = 6;
    DANGEROUS_DOWNLOAD_WARNING = 7;
    DANGEROUS_DOWNLOAD_BY_API = 10;
    URL_PASSWORD_PROTECTION_PHISHING = 12;
    DANGEROUS_DOWNLOAD_OPENED = 13;
    AD_SAMPLE = 14;
    URL_SUSPICIOUS = 15;
    BILLING = 16;
    APK_DOWNLOAD = 17;
    BLOCKED_AD_REDIRECT = 19;
    BLOCKED_AD_POPUP = 20;
  }

  message HTTPHeader {
    required bytes name = 1;
    optional bytes value = 2;
  }

  message HTTPRequest {
    message FirstLine {
      optional bytes verb = 1;
      optional bytes uri = 2;
      optional bytes version = 3;
    }

    optional FirstLine firstline = 1;
    repeated HTTPHeader headers = 2;
    optional bytes body = 3;

    // bodydigest and bodylength can be useful if the report does not
    // contain the body itself.
    optional bytes bodydigest = 4;  // 32-byte hex md5 digest of body.
    optional int32 bodylength = 5;  // length of body.
  }

  message HTTPResponse {
    message FirstLine {
      optional int32 code = 1;
      optional bytes message = 2;
      optional bytes version = 3;
    }

    optional FirstLine firstline = 1;
    repeated HTTPHeader headers = 2;
    optional bytes body = 3;
    optional bytes bodydigest = 4;  // 32-byte hex md5 digest of body.
    optional int32 bodylength = 5;  // length of body.
    optional bytes remote_ip = 6;   // IP of the server.
  }

  message Resource {
    required int32 id = 1;
    optional string url = 2;
    optional HTTPRequest request = 3;
    optional HTTPResponse response = 4;
    optional int32 parent_id = 5;
    repeated int32 child_ids = 6;
    optional string tag_name = 7;
  }

  optional ReportType type = 10;

  // Only set if ReportType is DANGEROUS_DOWNLOAD_RECOVERY,
  // DANGEROUS_DOWNLOAD_WARNING or DANGEROUS_DOWNLOAD_BY_API.
  optional ClientDownloadResponse.Verdict download_verdict = 11;

  // URL of the page in the address bar.
  optional string url = 1;

  // Must be set if the ReportType is not one of DANGEROUS_DOWNLOAD_RECOVERY,
  // DANGEROUS_DOWNLOAD_WARNING, DANGEROUS_DOWNLOAD_BY_API,
  // DANGEROUS_DOWNLOAD_OPENED, URL_PASSWORD_PROTECTION_PHISHING.
  optional string page_url = 2;

  optional string referrer_url = 3;

  repeated Resource resources = 4;

  // Contains the hierarchy of elements on the page (ie: the DOM). Some
  // elements can be Resources and will refer to the resources list (above).
  repeated HTMLElement dom = 16;

  // Whether the report is complete.
  optional bool complete = 5;

  // The ASN and country of the client IP. These fields are filled up by
  // csd_frontend
  repeated string client_asn = 6;
  optional string client_country = 7;

  // Whether user chose to proceed.
  optional bool did_proceed = 8;

  // Whether user visited this origin before.
  optional bool repeat_visit = 9;

  // The same token in ClientDownloadResponse or LoginReputationClientResponse.
  // This field is only set if its report type is DANGEROUS_DOWNLOAD_RECOVERY,
  // DANGEROUS_DOWNLOAD_WARNING, DANGEROUS_DOWNLOAD_BY_API,
  // URL_PASSWORD_PROTECTION_PHISHING, or DANGEROUS_DOWNLOAD_OPENED.
  optional bytes token = 15;

  enum SafeBrowsingUrlApiType {
    SAFE_BROWSING_URL_API_TYPE_UNSPECIFIED = 0;
    // Native implementation of Safe Browsing API v3 protocol.
    // Deprecated as of 2021-1. V3 protocol is not used anymore.
    PVER3_NATIVE = 1 [deprecated = true];
    // Native implementation of Safe Browsing API v4 protocol.
    PVER4_NATIVE = 2;
    // Android SafetyNet API.
    // https://developer.android.com/training/safetynet/safebrowsing.html
    ANDROID_SAFETYNET = 3;
    // Flywheel (data compression service).
    // Deprecated as of 2021-1. Data saver has been completely turned down.
    FLYWHEEL = 4 [deprecated = true];
    // Safe Browsing real time API.
    REAL_TIME = 5;
  }

  // The information propagated from the client about various environment
  // variables including SDK version, Google Play Services version and so on.
  message SafeBrowsingClientProperties {
    optional string client_version = 1;
    optional int64 google_play_services_version = 2;
    optional bool is_instant_apps = 3;
    optional SafeBrowsingUrlApiType url_api_type = 4;
  }
  optional SafeBrowsingClientProperties client_properties = 17;

  // Only set if report type is DANGEROUS_DOWNLOAD_EXECUTION.
  // True means user opened the folder where this download is in via browser.
  // False means user directly executed this download via download shelf or
  // other download UIs.
  optional bool show_download_in_folder = 18;

  // If we can find the complete referrer chain, this field will contains URLs
  // transitions from landing referrer to event in reverse chronological
  // order, i.e. event url comes first in this list, and landing referrer
  // comes last.
  repeated ReferrerChainEntry referrer_chain = 23;

  message DownloadItemInfo {
    // URL of the download payload.
    optional string url = 1;

    // This message contains various binary digests of the download payload.
    message Digests { optional bytes sha256 = 1; }
    optional Digests digests = 2;

    // This is the length in bytes of the download payload.
    optional int64 length = 3;

    // Name of the file where the download would be stored if the
    // download completes.  E.g., "bla.exe".
    optional string file_basename = 4;
  }

  optional DownloadItemInfo download_item_info = 24;

  // The SafetyNet ID of the Android device.
  // Deprecated, not launched.
  optional string safety_net_id = 25 [deprecated = true];

  optional ChromeUserPopulation population = 26;
}

// An HTML Element on the page (eg: iframe, div, script, etc).
message HTMLElement {
  // Id of this element.
  optional int32 id = 1;

  // The tag type of this element (eg: iframe, div, script, etc).
  optional string tag = 2;

  // IDs of elements that are children of this element.
  repeated int32 child_ids = 3;

  // If this element represents a Resource then this is the id of the
  // Resource, which contains additional data about the Resource. Otherwise
  // unset.
  optional int32 resource_id = 5;

  // An Attribute of the element (eg: id, border, foo etc) and its value.
  message Attribute {
    optional string name = 1;
    optional string value = 2;
  }
  repeated Attribute attribute = 6;

  optional bytes inner_html = 7;
}

// Protobuf for Chrome extension webstore install request.
message ExtensionWebStoreInstallRequest {
  // If we can find the complete referrer chain, this field will contain URL
  // transitions from landing referrer to event in reverse chronological
  // order, i.e. event url comes first in this list, and landing referrer
  // comes last.
  // For Safe Browsing Extended Reporting, if the referrer
  // chain is empty or partially missing, we will add/append recent navigation
  // events to this list. The type of these entries will be RECENT_NAVIGATION.
  repeated ReferrerChainEntry referrer_chain = 1;

  // Options and metadata about the above referrer chain.
  optional ReferrerChainOptions referrer_chain_options = 2;
}

// Protobuf for uploading Chrome extension telemetry reports.
message ExtensionTelemetryReportRequest {
  // Information about the Chrome extension.
  message ExtensionInfo {
    optional string id = 1;
    optional string version = 2;
    optional string name = 3;
    // Version install time.
    optional int64 install_timestamp_msec = 4;
  }

  // Information about the various telemetry signals.
  message SignalInfo {
    message TabsExecuteScriptInfo {
      message ScriptInfo {
        optional bytes hash = 1;
        // Number of times this script has been executed since
        // last report/browser start. This number is limited to
        // a configurable maximum (default max is 100).
        optional uint32 execution_count = 2;
      }
      repeated ScriptInfo scripts = 1;
      // The number of scripts that were not recorded because the max count was
      // exceeded.
      optional uint32 max_exceeded_script_count = 2;
    }

    optional TabsExecuteScriptInfo tabs_execute_script_info = 1;
  }

  // Single report structure consists of all the signals observed for a
  // single extension.
  message Report {
    optional ExtensionInfo extension = 1;
    repeated SignalInfo signals = 2;
  }

  // Report creation timestamp.
  optional int64 creation_timestamp_msec = 1;
  repeated Report reports = 2;
}

message ExtensionTelemetryResponse {}