123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796 |
- // Copyright 2015 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.
- #include "components/feedback/redaction_tool.h"
- #include <gtest/gtest.h>
- #include <set>
- #include <utility>
- #include "base/strings/string_util.h"
- #include "build/chromeos_buildflags.h"
- #include "components/feedback/pii_types.h"
- namespace feedback {
- const char kFakeFirstPartyID[] = "nkoccljplnhpfnfiajclkommnmllphnl";
- const char* const kFakeFirstPartyExtensionIDs[] = {kFakeFirstPartyID, nullptr};
- struct StringWithRedaction {
- // The raw version of the string before redaction. May contain PII sensitive
- // data.
- std::string pre_redaction;
- // The string that's redacted of PII sensitive data.
- std::string post_redaction;
- // The PII type that string contains. PIIType::kNone if the string doesn't
- // contain any PII sensitive data.
- PIIType pii_type;
- };
- // For better readability, put all the pre/post redaction strings in an array of
- // StringWithRedaction struct, and then convert that to two strings which become
- // the input and output of the redactor.
- const StringWithRedaction kStringsWithRedactions[] = {
- {"aaaaaaaa [SSID=123aaaaaa]aaaaa", // SSID.
- "aaaaaaaa [SSID=<SSID: 1>]aaaaa", PIIType::kSSID},
- {"aaaaaaaahttp://tets.comaaaaaaa", // URL.
- "aaaaaaaa<URL: 1>", PIIType::kURL},
- {"u:object_r:system_data_file:s0:c512,c768", // No PII, it is an SELinux
- // context.
- "u:object_r:system_data_file:s0:c512,c768", PIIType::kNone},
- {"aaaaaemail@example.comaaa", // Email address.
- "<email: 1>", PIIType::kEmail},
- {"example@@1234", // No PII, it is not a valid email address.
- "example@@1234", PIIType::kNone},
- {"255.255.155.2", // IP address.
- "<IPv4: 1>", PIIType::kIPAddress},
- {"255.255.155.255", // IP address.
- "<IPv4: 2>", PIIType::kIPAddress},
- {"127.0.0.1", // IPv4 loopback.
- "<127.0.0.0/8: 3>", PIIType::kIPAddress},
- {"127.255.0.1", // IPv4 loopback.
- "<127.0.0.0/8: 4>", PIIType::kIPAddress},
- {"0.0.0.0", // Any IPv4.
- "<0.0.0.0/8: 5>", PIIType::kIPAddress},
- {"0.255.255.255", // Any IPv4.
- "<0.0.0.0/8: 6>", PIIType::kIPAddress},
- {"10.10.10.100", // IPv4 private class A.
- "<10.0.0.0/8: 7>", PIIType::kIPAddress},
- {"10.10.10.100", // Intentional duplicate.
- "<10.0.0.0/8: 7>", PIIType::kIPAddress},
- {"10.10.10.101", // IPv4 private class A.
- "<10.0.0.0/8: 8>", PIIType::kIPAddress},
- {"10.255.255.255", // IPv4 private class A.
- "<10.0.0.0/8: 9>", PIIType::kIPAddress},
- {"172.16.0.0", // IPv4 private class B.
- "<172.16.0.0/12: 10>", PIIType::kIPAddress},
- {"172.31.255.255", // IPv4 private class B.
- "<172.16.0.0/12: 11>", PIIType::kIPAddress},
- {"172.11.5.5", // IP address.
- "<IPv4: 12>", PIIType::kIPAddress},
- {"172.111.5.5", // IP address.
- "<IPv4: 13>", PIIType::kIPAddress},
- {"192.168.0.0", // IPv4 private class C.
- "<192.168.0.0/16: 14>", PIIType::kIPAddress},
- {"192.168.255.255", // IPv4 private class C.
- "<192.168.0.0/16: 15>", PIIType::kIPAddress},
- {"192.169.2.120", // IP address.
- "<IPv4: 16>", PIIType::kIPAddress},
- {"169.254.0.1", // Link local.
- "<169.254.0.0/16: 17>", PIIType::kIPAddress},
- {"169.200.0.1", // IP address.
- "<IPv4: 18>", PIIType::kIPAddress},
- {"fe80::", // Link local.
- "<fe80::/10: 1>", PIIType::kIPAddress},
- {"fe80::ffff", // Link local.
- "<fe80::/10: 2>", PIIType::kIPAddress},
- {"febf:ffff::ffff", // Link local.
- "<fe80::/10: 3>", PIIType::kIPAddress},
- {"fecc::1111", // IP address.
- "<IPv6: 4>", PIIType::kIPAddress},
- {"224.0.0.24", // Multicast.
- "<224.0.0.0/4: 19>", PIIType::kIPAddress},
- {"240.0.0.0", // IP address.
- "<IPv4: 20>", PIIType::kIPAddress},
- {"255.255.255.255", // Broadcast.
- "255.255.255.255", PIIType::kNone},
- {"100.115.92.92", // ChromeOS.
- "100.115.92.92", PIIType::kNone},
- {"100.115.91.92", // IP address.
- "<IPv4: 21>", PIIType::kIPAddress},
- {"1.1.1.1", // DNS
- "1.1.1.1", PIIType::kNone},
- {"8.8.8.8", // DNS
- "8.8.8.8", PIIType::kNone},
- {"8.8.4.4", // DNS
- "8.8.4.4", PIIType::kNone},
- {"8.8.8.4", // IP address.
- "<IPv4: 22>", PIIType::kIPAddress},
- {"255.255.259.255", // Not an IP address.
- "255.255.259.255", PIIType::kNone},
- {"255.300.255.255", // Not an IP address.
- "255.300.255.255", PIIType::kNone},
- {"3-1.2.3.4", // USB path, not an IP address.
- "3-1.2.3.4", PIIType::kNone},
- {"Revision: 81600.0000.00.29.19.16_DO", // Modem firmware
- "Revision: 81600.0000.00.29.19.16_DO", PIIType::kNone},
- {"aaaa123.123.45.4aaa", // IP address.
- "aaaa<IPv4: 23>aaa", PIIType::kIPAddress},
- {"11:11;11::11", // IP address.
- "11:11;<IPv6: 5>", PIIType::kIPAddress},
- {"11::11", // IP address.
- "<IPv6: 5>", PIIType::kIPAddress},
- {"11:11:abcdef:0:0:0:0:0", // No PII.
- "11:11:abcdef:0:0:0:0:0", PIIType::kNone},
- {"::", // Unspecified.
- "::", PIIType::kNone},
- {"::1", // Local host.
- "::1", PIIType::kNone},
- {"Instance::Set", // Ignore match, no PII.
- "Instance::Set", PIIType::kNone},
- {"Instant::ff", // Ignore match, no PII.
- "Instant::ff", PIIType::kNone},
- {"net::ERR_CONN_TIMEOUT", // Ignore match, no PII.
- "net::ERR_CONN_TIMEOUT", PIIType::kNone},
- {"ff01::1", // All nodes address (interface local).
- "ff01::1", PIIType::kNone},
- {"ff01::2", // All routers (interface local).
- "ff01::2", PIIType::kNone},
- {"ff01::3", // Multicast (interface local).
- "<ff01::/16: 6>", PIIType::kIPAddress},
- {"ff02::1", // All nodes address (link local).
- "ff02::1", PIIType::kNone},
- {"ff02::2", // All routers (link local).
- "ff02::2", PIIType::kNone},
- {"ff02::3", // Multicast (link local).
- "<ff02::/16: 7>", PIIType::kIPAddress},
- {"ff02::fb", // mDNSv6 (link local).
- "<ff02::/16: 8>", PIIType::kIPAddress},
- {"ff08::fb", // mDNSv6.
- "<IPv6: 9>", PIIType::kIPAddress},
- {"ff0f::101", // All NTP servers.
- "<IPv6: 10>", PIIType::kIPAddress},
- {"::ffff:cb0c:10ea", // IPv4-mapped IPV6 (IP address).
- "<IPv6: 11>", PIIType::kIPAddress},
- {"::ffff:a0a:a0a", // IPv4-mapped IPV6 (private class A).
- "<M 10.0.0.0/8: 12>", PIIType::kIPAddress},
- {"::ffff:a0a:a0a", // Intentional duplicate.
- "<M 10.0.0.0/8: 12>", PIIType::kIPAddress},
- {"::ffff:ac1e:1e1e", // IPv4-mapped IPV6 (private class B).
- "<M 172.16.0.0/12: 13>", PIIType::kIPAddress},
- {"::ffff:c0a8:640a", // IPv4-mapped IPV6 (private class C).
- "<M 192.168.0.0/16: 14>", PIIType::kIPAddress},
- {"::ffff:6473:5c01", // IPv4-mapped IPV6 (Chrome).
- "<M 100.115.92.1: 15>", PIIType::kIPAddress},
- {"64:ff9b::a0a:a0a", // IPv4-translated 6to4 IPV6 (private class A).
- "<T 10.0.0.0/8: 16>", PIIType::kIPAddress},
- {"64:ff9b::6473:5c01", // IPv4-translated 6to4 IPV6 (Chrome).
- "<T 100.115.92.1: 17>", PIIType::kIPAddress},
- {"::0101:ffff:c0a8:640a", // IP address.
- "<IPv6: 18>", PIIType::kIPAddress},
- {"aa:aa:aa:aa:aa:aa", // MAC address (BSSID).
- "[MAC OUI=aa:aa:aa IFACE=1]", PIIType::kMACAddress},
- {"chrome://resources/foo", // Secure chrome resource, exempt.
- "chrome://resources/foo", PIIType::kNone},
- {"chrome://settings/crisper.js", // Exempt settings URLs.
- "chrome://settings/crisper.js", PIIType::kNone},
- // Exempt first party extension.
- {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js",
- "chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js",
- PIIType::kNone},
- {"chrome://resources/f?user=bar", // Potentially PII in parameter.
- "<URL: 2>", PIIType::kURL},
- {"chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/foobar.js?bar=x",
- "<URL: 3>", PIIType::kURL}, // Potentially PII in parameter.
- {"/root/27540283740a0897ab7c8de0f809add2bacde78f/foo",
- "/root/<HASH:2754 1>/foo", PIIType::kStableIdentifier}, // Hash string.
- {"B3mcFTkQAHofv94DDTUuVJGGEI/BbzsyDncplMCR2P4=", "<UID: 1>",
- PIIType::kStableIdentifier},
- #if BUILDFLAG(IS_CHROMEOS_ASH) // We only redact Android paths on Chrome OS.
- // Allowed android storage path.
- {"112K\t/home/root/deadbeef1234/android-data/data/system_de",
- "112K\t/home/root/deadbeef1234/android-data/data/system_de",
- PIIType::kNone},
- // Redacted app-specific storage path.
- {"8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/de",
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/d_",
- PIIType::kAndroidAppStoragePath},
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- };
- class RedactionToolTest : public testing::Test {
- protected:
- std::string RedactMACAddresses(const std::string& input) {
- return redactor_.RedactMACAddresses(input, nullptr);
- }
- std::string RedactHashes(const std::string& input) {
- return redactor_.RedactHashes(input, nullptr);
- }
- std::string RedactAndroidAppStoragePaths(const std::string& input) {
- return redactor_.RedactAndroidAppStoragePaths(input, nullptr);
- }
- std::string RedactCustomPatterns(const std::string& input) {
- return redactor_.RedactAndKeepSelectedCustomPatterns(
- input,
- /*pii_types_to_keep=*/{});
- }
- std::string RedactCustomPatternWithContext(
- const std::string& input,
- const CustomPatternWithAlias& pattern) {
- return redactor_.RedactCustomPatternWithContext(input, pattern, nullptr);
- }
- std::string RedactCustomPatternWithoutContext(
- const std::string& input,
- const CustomPatternWithAlias& pattern) {
- return redactor_.RedactCustomPatternWithoutContext(input, pattern, nullptr);
- }
- RedactionTool redactor_{kFakeFirstPartyExtensionIDs};
- };
- TEST_F(RedactionToolTest, Redact) {
- EXPECT_EQ("", redactor_.Redact(""));
- EXPECT_EQ("foo\nbar\n", redactor_.Redact("foo\nbar\n"));
- // Make sure MAC address redaction is invoked.
- EXPECT_EQ("[MAC OUI=02:46:8a IFACE=1]",
- redactor_.Redact("02:46:8a:ce:13:57"));
- // Make sure hash redaction is invoked.
- EXPECT_EQ("<HASH:1122 1>",
- redactor_.Redact("11223344556677889900AABBCCDDEEFF"));
- // Make sure custom pattern redaction is invoked.
- EXPECT_EQ("Cell ID: '<CellID: 1>'", RedactCustomPatterns("Cell ID: 'A1B2'"));
- // Make sure UUIDs are redacted.
- EXPECT_EQ(
- "REQUEST localhost - - \"POST /printers/<UUID: 1> HTTP/1.1\" 200 291 "
- "Create-Job successful-ok",
- redactor_.Redact(
- "REQUEST localhost - - \"POST /printers/"
- "cb738a9f-6433-4d95-a81e-94e4ae0ed30b HTTP/1.1\" 200 291 Create-Job "
- "successful-ok"));
- EXPECT_EQ(
- "REQUEST localhost - - \"POST /printers/<UUID: 2> HTTP/1.1\" 200 286 "
- "Create-Job successful-ok",
- redactor_.Redact(
- "REQUEST localhost - - \"POST /printers/"
- "d17188da-9cd3-44f4-b148-3e1d748a3b0f HTTP/1.1\" 200 286 Create-Job "
- "successful-ok"));
- }
- TEST_F(RedactionToolTest, RedactMACAddresses) {
- EXPECT_EQ("", RedactMACAddresses(""));
- EXPECT_EQ("foo\nbar\n", RedactMACAddresses("foo\nbar\n"));
- EXPECT_EQ("11:22:33:44:55", RedactMACAddresses("11:22:33:44:55"));
- EXPECT_EQ("[MAC OUI=aa:bb:cc IFACE=1]",
- RedactMACAddresses("aa:bb:cc:dd:ee:ff"));
- EXPECT_EQ("[MAC OUI=aa:bb:cc IFACE=1]",
- RedactMACAddresses("aa_bb_cc_dd_ee_ff"));
- EXPECT_EQ("[MAC OUI=aa:bb:cc IFACE=1]",
- RedactMACAddresses("aa-bb-cc-dd-ee-ff"));
- EXPECT_EQ("00:00:00:00:00:00", RedactMACAddresses("00:00:00:00:00:00"));
- EXPECT_EQ("ff:ff:ff:ff:ff:ff", RedactMACAddresses("ff:ff:ff:ff:ff:ff"));
- EXPECT_EQ(
- "BSSID: [MAC OUI=aa:bb:cc IFACE=1] in the middle\n"
- "[MAC OUI=bb:cc:dd IFACE=2] start of line\n"
- "end of line [MAC OUI=aa:bb:cc IFACE=1]\n"
- "no match across lines aa:bb:cc:\n"
- "dd:ee:ff two on the same line:\n"
- "x [MAC OUI=bb:cc:dd IFACE=2] [MAC OUI=cc:dd:ee IFACE=3] x\n",
- RedactMACAddresses("BSSID: aa:bb:cc:dd:ee:ff in the middle\n"
- "bb:cc:dd:ee:ff:00 start of line\n"
- "end of line aa:bb:cc:dd:ee:ff\n"
- "no match across lines aa:bb:cc:\n"
- "dd:ee:ff two on the same line:\n"
- "x bb:cc:dd:ee:ff:00 cc:dd:ee:ff:00:11 x\n"));
- EXPECT_EQ("Remember [MAC OUI=bb:cc:dd IFACE=2]?",
- RedactMACAddresses("Remember bB:Cc:DD:ee:ff:00?"));
- }
- TEST_F(RedactionToolTest, RedactHashes) {
- EXPECT_EQ("", RedactHashes(""));
- EXPECT_EQ("foo\nbar\n", RedactHashes("foo\nbar\n"));
- // Too short.
- EXPECT_EQ("11223344556677889900aabbccddee",
- RedactHashes("11223344556677889900aabbccddee"));
- // Not the right length.
- EXPECT_EQ("11223344556677889900aabbccddeeff1122",
- RedactHashes("11223344556677889900aabbccddeeff1122"));
- // Too long.
- EXPECT_EQ(
- "11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff11",
- RedactHashes("11223344556677889900aabbccddeeff11223344556677889900aabb"
- "ccddeeff11"));
- // Test all 3 valid lengths.
- EXPECT_EQ("<HASH:aabb 1>", RedactHashes("aabbccddeeff00112233445566778899"));
- EXPECT_EQ("<HASH:aabb 2>",
- RedactHashes("aabbccddeeff00112233445566778899aabbccdd"));
- EXPECT_EQ(
- "<HASH:9988 3>",
- RedactHashes(
- "99887766554433221100ffeeddccbbaaaabbccddeeff00112233445566778899"));
- // Skip 32 byte hashes that have a at least 3 whitespace chars before it.
- EXPECT_EQ(" <HASH:aabb 1>",
- RedactHashes(" aabbccddeeff00112233445566778899"));
- EXPECT_EQ(" aabbccddeeff00112233445566778899",
- RedactHashes(" aabbccddeeff00112233445566778899"));
- // Multiline test.
- EXPECT_EQ(
- "Hash value=<HASH:aabb 1>, should be replaced as\n"
- "well as /<HASH:aabb 1>/ and mixed case of\n"
- "<HASH:aabb 1> but we don't go across lines\n"
- "aabbccddeeff\n00112233445566778899 but allow multiple on a line "
- "<HASH:aabb 4>-"
- "<HASH:0011 5>\n",
- RedactHashes(
- "Hash value=aabbccddeeff00112233445566778899, should be replaced as\n"
- "well as /aabbccddeeff00112233445566778899/ and mixed case of\n"
- "AaBbCCddEeFf00112233445566778899 but we don't go across lines\n"
- "aabbccddeeff\n00112233445566778899 but allow multiple on a line "
- "aabbccddeeffaabbccddeeffaabbccddeeffaabb-"
- "00112233445566778899aabbccddeeff\n"));
- }
- TEST_F(RedactionToolTest, RedactCustomPatterns) {
- EXPECT_EQ("", RedactCustomPatterns(""));
- EXPECT_EQ("Cell ID: '<CellID: 1>'", RedactCustomPatterns("Cell ID: 'A1B2'"));
- EXPECT_EQ("Cell ID: '<CellID: 2>'", RedactCustomPatterns("Cell ID: 'C1D2'"));
- EXPECT_EQ("foo Cell ID: '<CellID: 1>' bar",
- RedactCustomPatterns("foo Cell ID: 'A1B2' bar"));
- EXPECT_EQ("foo Location area code: '<LocAC: 1>' bar",
- RedactCustomPatterns("foo Location area code: 'A1B2' bar"));
- EXPECT_EQ("foo\na SSID='<SSID: 1>' b\n'",
- RedactCustomPatterns("foo\na SSID='Joe's' b\n'"));
- EXPECT_EQ("ssid '<SSID: 2>'", RedactCustomPatterns("ssid 'My AP'"));
- EXPECT_EQ("bssid 'aa:bb'", RedactCustomPatterns("bssid 'aa:bb'"));
- EXPECT_EQ("Scan SSID - hexdump(len=6): <SSIDHex: 1>\nfoo",
- RedactCustomPatterns(
- "Scan SSID - hexdump(len=6): 47 6f 6f 67 6c 65\nfoo"));
- EXPECT_EQ(
- "a\nb [SSID=<SSID: 3>] [SSID=<SSID: 1>] [SSID=foo\nbar] b",
- RedactCustomPatterns("a\nb [SSID=foo] [SSID=Joe's] [SSID=foo\nbar] b"));
- EXPECT_EQ("ssid=\"<SSID: 4>\"",
- RedactCustomPatterns("ssid=\"LittleTsunami\""));
- EXPECT_EQ("* SSID=<SSID: 5>", RedactCustomPatterns("* SSID=agnagna"));
- EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 6>",
- RedactCustomPatterns(
- "Specifier: <ArcNetworkFactory#1> SSID: \"GoogleGuest\""));
- EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 7>",
- RedactCustomPatterns(
- "Specifier: <ArcNetworkFactory#1> SSID: 'GoogleGuest'"));
- EXPECT_EQ("Specifier: <ArcNetworkFactory#1> SSID: <SSID: 8>",
- RedactCustomPatterns(
- "Specifier: <ArcNetworkFactory#1> SSID: GoogleGuest"));
- EXPECT_EQ("SerialNumber: <Serial: 1>",
- RedactCustomPatterns("SerialNumber: 1217D7EF"));
- EXPECT_EQ("serial number: <Serial: 2>",
- RedactCustomPatterns("serial number: 50C971FEE7F3x010900"));
- EXPECT_EQ("SerialNumber: <Serial: 3>",
- RedactCustomPatterns("SerialNumber: EVT23-17BA01-004"));
- EXPECT_EQ("serial=\"<Serial: 4>\"",
- RedactCustomPatterns("serial=\"1234AA5678\""));
- EXPECT_EQ("\"serial_number\"=\"<Serial: 1>\"",
- RedactCustomPatterns("\"serial_number\"=\"1217D7EF\""));
- EXPECT_EQ("SerialNumber: <Serial: 5>",
- RedactCustomPatterns("SerialNumber: 5:00:14.0"));
- EXPECT_EQ("Serial: <Serial: 6>",
- RedactCustomPatterns("Serial: ABCEFG\x01kjmn-as:342/234\\432"));
- // Don't overly redact serial numbers, we only do this for a specific
- // formatting case for edid-decode.
- EXPECT_EQ("Foo serial number 123",
- RedactCustomPatterns("Foo serial number 123"));
- EXPECT_EQ("Foo Serial Number <Serial: 7>",
- RedactCustomPatterns("Foo Serial Number 123"));
- // redact serial number separated by a | with the label "serial"
- EXPECT_EQ("serial | <Serial: 8>",
- RedactCustomPatterns("serial | 0x1cc04416"));
- EXPECT_EQ("serial |<Serial: 9>",
- RedactCustomPatterns("serial |0x1cc04417"));
- EXPECT_EQ("serial|<Serial: 10>", RedactCustomPatterns("serial|0x1cc04418"));
- EXPECT_EQ("serial|<Serial: 11>", RedactCustomPatterns("serial|agnagna"));
- // redact attested device id that is also a serial number
- EXPECT_EQ("\"attested_device_id\"=\"<Serial: 12>\"",
- RedactCustomPatterns("\"attested_device_id\"=\"5CD045B0DZ\""));
- EXPECT_EQ("\"attested_device_id\"=\"<Serial: 13>\"",
- RedactCustomPatterns("\"attested_device_id\"=\"5CD04-5B0DZ\""));
- // The dash cannot appear first or last.
- EXPECT_EQ("\"attested_device_id\"=\"-5CD045B0DZ\"",
- RedactCustomPatterns("\"attested_device_id\"=\"-5CD045B0DZ\""));
- EXPECT_EQ("\"attested_device_id\"=\"5CD045B0DZ-\"",
- RedactCustomPatterns("\"attested_device_id\"=\"5CD045B0DZ-\""));
- EXPECT_EQ("\"gaia_id\":\"<GAIA: 1>\"",
- RedactCustomPatterns("\"gaia_id\":\"1234567890\""));
- EXPECT_EQ("gaia_id='<GAIA: 2>'", RedactCustomPatterns("gaia_id='987654321'"));
- EXPECT_EQ("{id: <GAIA: 1>, email:",
- RedactCustomPatterns("{id: 1234567890, email:"));
- EXPECT_EQ("<email: 1>", RedactCustomPatterns("foo@bar.com"));
- EXPECT_EQ("Email: <email: 1>.", RedactCustomPatterns("Email: foo@bar.com."));
- EXPECT_EQ("Email:\n<email: 2>\n",
- RedactCustomPatterns("Email:\nfooooo@bar.com\n"));
- EXPECT_EQ("[<IPv6: 1>]",
- RedactCustomPatterns("[2001:0db8:0000:0000:0000:ff00:0042:8329]"));
- EXPECT_EQ("[<IPv6: 2>]",
- RedactCustomPatterns("[2001:db8:0:0:0:ff00:42:8329]"));
- EXPECT_EQ("[<IPv6: 3>]", RedactCustomPatterns("[2001:db8::ff00:42:8329]"));
- EXPECT_EQ("[<IPv6: 4>]", RedactCustomPatterns("[aa::bb]"));
- EXPECT_EQ("State::Abort", RedactCustomPatterns("State::Abort"));
- // Real IPv4 address
- EXPECT_EQ("<IPv4: 1>", RedactCustomPatterns("192.160.0.1"));
- // Non-PII IPv4 address (see MaybeScrubIPAddress)
- EXPECT_EQ("255.255.255.255", RedactCustomPatterns("255.255.255.255"));
- // Not an actual IPv4 address
- EXPECT_EQ("75.748.86.91", RedactCustomPatterns("75.748.86.91"));
- // USB Path - not an actual IPv4 Address
- EXPECT_EQ("4-3.3.3.3", RedactCustomPatterns("4-3.3.3.3"));
- // ModemManager modem firmware revisions - not actual IPv4 Addresses
- EXPECT_EQ("Revision: 81600.0000.00.29.19.16_DO",
- RedactCustomPatterns("Revision: 81600.0000.00.29.19.16_DO"));
- EXPECT_EQ("Revision: 11.608.09.01.21",
- RedactCustomPatterns("Revision: 11.608.09.01.21"));
- EXPECT_EQ("Revision: 11.208.09.01.21",
- RedactCustomPatterns("Revision: 11.208.09.01.21"));
- EXPECT_EQ("Revision: BD_3GHAP673A4V1.0.0B02",
- RedactCustomPatterns("Revision: BD_3GHAP673A4V1.0.0B02"));
- EXPECT_EQ("Revision: 2.5.21Hd (Date: Jun 17 2008, Time: 12:30:47)",
- RedactCustomPatterns(
- "Revision: 2.5.21Hd (Date: Jun 17 2008, Time: 12:30:47)"));
- EXPECT_EQ(
- "Revision: 9.5.05.01-02 [2006-10-20 17:19:09]",
- RedactCustomPatterns("Revision: 9.5.05.01-02 [2006-10-20 17:19:09]"));
- EXPECT_EQ("Revision: LQA0021.1.1_M573A",
- RedactCustomPatterns("Revision: LQA0021.1.1_M573A"));
- EXPECT_EQ("Revision: 10.10.10.10",
- RedactCustomPatterns("Revision: 10.10.10.10"));
- EXPECT_EQ("<URL: 1>", RedactCustomPatterns("http://example.com/foo?test=1"));
- EXPECT_EQ("Foo <URL: 2> Bar",
- RedactCustomPatterns("Foo http://192.168.0.1/foo?test=1#123 Bar"));
- const char* kURLs[] = {
- "http://example.com/foo?test=1",
- "http://userid:password@example.com:8080",
- "http://userid:password@example.com:8080/",
- "http://@example.com",
- "http://192.168.0.1",
- "http://192.168.0.1/",
- "http://اختبار.com",
- "http://test.com/foo(bar)baz.html",
- "http://test.com/foo%20bar",
- "ftp://test:tester@test.com",
- "chrome://extensions/",
- "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/options.html",
- "http://example.com/foo?email=foo@bar.com",
- "rtsp://root@example.com/",
- "https://aaaaaaaaaaaaaaaa.com",
- "file:///var/log/messages",
- "file:///usr/local/home/iby/web%20page%20test.html",
- };
- for (size_t i = 0; i < std::size(kURLs); ++i) {
- SCOPED_TRACE(kURLs[i]);
- std::string got = RedactCustomPatterns(kURLs[i]);
- EXPECT_TRUE(
- base::StartsWith(got, "<URL: ", base::CompareCase::INSENSITIVE_ASCII));
- EXPECT_TRUE(base::EndsWith(got, ">", base::CompareCase::INSENSITIVE_ASCII));
- }
- // Test that "Android:" is not considered a schema with empty hier part.
- EXPECT_EQ("The following applies to Android:",
- RedactCustomPatterns("The following applies to Android:"));
- }
- TEST_F(RedactionToolTest, RedactCustomPatternWithContext) {
- // The PIIType for the CustomPatternWithAlias is not relevant, only for
- // testing.
- const CustomPatternWithAlias kPattern1 = {"ID", "(\\b(?i)id:? ')(\\d+)(')",
- PIIType::kStableIdentifier};
- const CustomPatternWithAlias kPattern2 = {"ID", "(\\b(?i)id=')(\\d+)(')",
- PIIType::kStableIdentifier};
- const CustomPatternWithAlias kPattern3 = {"IDG", "(\\b(?i)idg=')(\\d+)(')",
- PIIType::kLocationInfo};
- EXPECT_EQ("", RedactCustomPatternWithContext("", kPattern1));
- EXPECT_EQ("foo\nbar\n",
- RedactCustomPatternWithContext("foo\nbar\n", kPattern1));
- EXPECT_EQ("id '<ID: 1>'",
- RedactCustomPatternWithContext("id '2345'", kPattern1));
- EXPECT_EQ("id '<ID: 2>'",
- RedactCustomPatternWithContext("id '1234'", kPattern1));
- EXPECT_EQ("id: '<ID: 2>'",
- RedactCustomPatternWithContext("id: '1234'", kPattern1));
- EXPECT_EQ("ID: '<ID: 1>'",
- RedactCustomPatternWithContext("ID: '2345'", kPattern1));
- EXPECT_EQ("x1 id '<ID: 1>' 1x id '<ID: 2>'\nid '<ID: 1>'\n",
- RedactCustomPatternWithContext(
- "x1 id '2345' 1x id '1234'\nid '2345'\n", kPattern1));
- // Different pattern with same alias should reuse the replacements.
- EXPECT_EQ("id='<ID: 2>'",
- RedactCustomPatternWithContext("id='1234'", kPattern2));
- // Different alias should not reuse replacement from another pattern.
- EXPECT_EQ("idg='<IDG: 1>'",
- RedactCustomPatternWithContext("idg='1234'", kPattern3));
- EXPECT_EQ("x<FOO: 1>z",
- RedactCustomPatternWithContext("xyz", {"FOO", "()(y+)()"}));
- }
- TEST_F(RedactionToolTest, RedactCustomPatternWithoutContext) {
- // The PIIType for the CustomPatternWithAlias here is not relevant, only for
- // testing.
- CustomPatternWithAlias kPattern = {"pattern", "(o+)", PIIType::kEmail};
- EXPECT_EQ("", RedactCustomPatternWithoutContext("", kPattern));
- EXPECT_EQ("f<pattern: 1>\nf<pattern: 2>z\nf<pattern: 1>l\n",
- RedactCustomPatternWithoutContext("fo\nfooz\nfol\n", kPattern));
- }
- TEST_F(RedactionToolTest, RedactChunk) {
- std::string redaction_input;
- std::string redaction_output;
- for (const auto& s : kStringsWithRedactions) {
- redaction_input.append(s.pre_redaction).append("\n");
- redaction_output.append(s.post_redaction).append("\n");
- }
- EXPECT_EQ(redaction_output, redactor_.Redact(redaction_input));
- }
- TEST_F(RedactionToolTest, RedactAndKeepSelected) {
- std::string redaction_input;
- std::string redaction_output;
- for (const auto& s : kStringsWithRedactions) {
- redaction_input.append(s.pre_redaction).append("\n");
- redaction_output.append(s.post_redaction).append("\n");
- }
- // Test RedactAndKeepSelected() with no PII type to keep.
- EXPECT_EQ(redaction_output,
- redactor_.RedactAndKeepSelected(redaction_input, {}));
- // Test RedactAndKeepSelected() by only keeping IP addresses in the redacted
- // output.
- std::string redaction_output_ip;
- for (const auto& s : kStringsWithRedactions) {
- if (s.pii_type == PIIType::kIPAddress) {
- redaction_output_ip.append(s.pre_redaction).append("\n");
- } else {
- redaction_output_ip.append(s.post_redaction).append("\n");
- }
- }
- EXPECT_EQ(redaction_output_ip, redactor_.RedactAndKeepSelected(
- redaction_input, {PIIType::kIPAddress}));
- // Test RedactAndKeepSelected() by keeping MAC addresses and hashes in the
- // redacted output. The hashes that URLs and Android storage paths contain
- // will be redacted with the URL or Android storage path that they're part of.
- std::string redaction_output_mac_and_hashes;
- for (const auto& s : kStringsWithRedactions) {
- if (s.pii_type == PIIType::kMACAddress ||
- s.pii_type == PIIType::kStableIdentifier) {
- redaction_output_mac_and_hashes.append(s.pre_redaction).append("\n");
- } else {
- redaction_output_mac_and_hashes.append(s.post_redaction).append("\n");
- }
- }
- EXPECT_EQ(
- redaction_output_mac_and_hashes,
- redactor_.RedactAndKeepSelected(
- redaction_input, {PIIType::kMACAddress, PIIType::kStableIdentifier}));
- }
- TEST_F(RedactionToolTest, RedactUid) {
- EXPECT_EQ("<UID: 1>",
- redactor_.RedactAndKeepSelected(
- "B3mcFTkQAHofv94DDTUuVJGGEI/BbzsyDncplMCR2P4=", {}));
- }
- TEST_F(RedactionToolTest, RedactAndKeepSelectedHashes) {
- // Array of pairs containing pre/post redaction versions of the same string.
- // Will be appended to create input and expected output for the test. Keep
- // URLs and Android app storage paths but redact hashes. URLs and Android app
- // storage paths that contain hashes will be partially redacted.
- const std::pair<std::string, std::string> redaction_strings_with_hashes[] = {
- {"chrome://resources/"
- "f?user="
- "99887766554433221100ffeeddccbbaaaabbccddeeff00112233445566778899",
- "chrome://resources/f?user=<HASH:9988 1>"}, // URL that contains a hash.
- {"/root/27540283740a0897ab7c8de0f809add2bacde78f/foo",
- "/root/<HASH:2754 2>/foo"}, // String that contains a hash.
- {"this is the user hash that we need to redact "
- "aabbccddeeff00112233445566778899",
- "this is the user hash that we need to redact <HASH:aabb 3>"}, // String
- // that
- // contains
- // a hash.
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- {"8.0K\t/home/root/aabbccddeeff00112233445566778899/"
- "android-data/data/data/pa.ckage2/de", // Android app storage
- // path that contains a
- // hash.
- "8.0K\t/home/root/<HASH:aabb 3>/android-data/data/data/pa.ckage2/de"}
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- };
- std::string redaction_input;
- std::string redaction_output;
- for (const auto& s : redaction_strings_with_hashes) {
- redaction_input.append(s.first).append("\n");
- redaction_output.append(s.second).append("\n");
- }
- EXPECT_EQ(
- redaction_output,
- redactor_.RedactAndKeepSelected(
- redaction_input, {PIIType::kAndroidAppStoragePath, PIIType::kURL}));
- }
- TEST_F(RedactionToolTest, DetectPII) {
- std::string redaction_input;
- for (const auto& s : kStringsWithRedactions) {
- redaction_input.append(s.pre_redaction).append("\n");
- }
- std::map<PIIType, std::set<std::string>> pii_in_data {
- #if BUILDFLAG(IS_CHROMEOS_ASH) // We only detect Android paths on Chrome OS.
- {PIIType::kAndroidAppStoragePath, {"/de"}},
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- {PIIType::kSSID, {"123aaaaaa"}},
- {PIIType::kURL,
- {"http://tets.comaaaaaaa", "chrome://resources/f?user=bar",
- "chrome-extension://nkoccljplnhpfnfiajclkommnmllphnl/"
- "foobar.js?bar=x"}},
- {PIIType::kEmail, {"aaaaaemail@example.comaaa"}},
- {PIIType::kIPAddress,
- {
- "255.255.155.2",
- "255.255.155.255",
- "127.0.0.1",
- "127.255.0.1",
- "0.0.0.0",
- "0.255.255.255",
- "10.10.10.100",
- "10.10.10.101",
- "10.255.255.255",
- "172.16.0.0",
- "172.31.255.255",
- "172.11.5.5",
- "172.111.5.5",
- "192.168.0.0",
- "192.168.255.255",
- "192.169.2.120",
- "169.254.0.1",
- "169.200.0.1",
- "224.0.0.24",
- "240.0.0.0",
- "100.115.91.92",
- "8.8.8.4",
- "123.123.45.4",
- "fe80::",
- "fe80::ffff",
- "febf:ffff::ffff",
- "fecc::1111",
- "11::11",
- "ff01::3",
- "ff02::3",
- "ff02::fb",
- "ff08::fb",
- "ff0f::101",
- "::ffff:cb0c:10ea",
- "::ffff:a0a:a0a",
- "::ffff:ac1e:1e1e",
- "::ffff:c0a8:640a",
- "::ffff:6473:5c01",
- "64:ff9b::a0a:a0a",
- "64:ff9b::6473:5c01",
- "::0101:ffff:c0a8:640a",
- }},
- {PIIType::kMACAddress, {"aa:aa:aa:aa:aa:aa"}}, {
- PIIType::kStableIdentifier, {
- "27540283740a0897ab7c8de0f809add2bacde78f",
- "B3mcFTkQAHofv94DDTUuVJGGEI/BbzsyDncplMCR2P4=",
- }
- }
- };
- EXPECT_EQ(pii_in_data, redactor_.Detect(redaction_input));
- }
- #if BUILDFLAG(IS_CHROMEOS_ASH) // We only redact Android paths on Chrome OS.
- TEST_F(RedactionToolTest, RedactAndroidAppStoragePaths) {
- EXPECT_EQ("", RedactAndroidAppStoragePaths(""));
- EXPECT_EQ("foo\nbar\n", RedactAndroidAppStoragePaths("foo\nbar\n"));
- constexpr char kDuOutput[] =
- "112K\t/home/root/deadbeef1234/android-data/data/system_de\n"
- // /data/data will be modified by the redactor.
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pack.age1/bc\n"
- "24K\t/home/root/deadbeef1234/android-data/data/data/pack.age1\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/de\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/de/"
- "\xe3\x81\x82\n"
- "8.1K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/de/"
- "\xe3\x81\x82\xe3\x81\x83\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/ef\n"
- "24K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/app/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/app/pack.age1/bc\n"
- "24K\t/home/root/deadbeef1234/android-data/data/app/pack.age1\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1/bc\n"
- "24K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1\n"
- "78M\t/home/root/deadbeef1234/android-data/data/data\n"
- "key=value path=/data/data/pack.age1/bc key=value\n"
- "key=value path=/data/user_de/0/pack.age1/bc key=value\n"
- "key=value exe=/data/app/pack.age1/bc key=value\n";
- constexpr char kDuOutputRedacted[] =
- "112K\t/home/root/deadbeef1234/android-data/data/system_de\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pack.age1/b_\n"
- "24K\t/home/root/deadbeef1234/android-data/data/data/pack.age1\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/d_\n"
- // The non-ASCII directory names will become '*_'.
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/d_/*_\n"
- "8.1K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/d_/*_\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2/e_\n"
- "24K\t/home/root/deadbeef1234/android-data/data/data/pa.ckage2\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/app/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/app/pack.age1/b_\n"
- "24K\t/home/root/deadbeef1234/android-data/data/app/pack.age1\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1/a\n"
- "8.0K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1/b_\n"
- "24K\t/home/root/deadbeef1234/android-data/data/user_de/0/pack.age1\n"
- "78M\t/home/root/deadbeef1234/android-data/data/data\n"
- "key=value path=/data/data/pack.age1/b_ key=value\n"
- "key=value path=/data/user_de/0/pack.age1/b_ key=value\n"
- "key=value exe=/data/app/pack.age1/b_ key=value\n";
- EXPECT_EQ(kDuOutputRedacted, RedactAndroidAppStoragePaths(kDuOutput));
- }
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- TEST_F(RedactionToolTest, RedactBlockDevices) {
- // Test cases in the form {input, output}.
- std::pair<std::string, std::string> test_cases[] = {
- // UUIDs that come from the 'blkid' tool.
- {"PTUUID=\"985dff64-9c0f-3f49-945b-2d8c2e0238ec\"",
- "PTUUID=\"<UUID: 1>\""},
- {"UUID=\"E064-868C\"", "UUID=\"<UUID: 2>\""},
- {"PARTUUID=\"7D242B2B1C751832\"", "PARTUUID=\"<UUID: 3>\""},
- // Volume labels.
- {"LABEL=\"ntfs\"", "LABEL=\"<Volume Label: 1>\""},
- {"PARTLABEL=\"SD Card\"", "PARTLABEL=\"<Volume Label: 2>\""},
- // LVM UUIDd.
- {"{\"pv_fmt\":\"lvm2\", "
- "\"pv_uuid\":\"duD18x-P7QE-sTya-SaeO-aq07-YgEq-xj8UEz\", "
- "\"dev_size\":\"230.33g\"}",
- "{\"pv_fmt\":\"lvm2\", \"pv_uuid\":\"<UUID: 4>\", "
- "\"dev_size\":\"230.33g\"}"},
- {"{\"lv_uuid\":\"lKYORl-TWDP-OFLT-yDnB-jlQ7-aQrE-AwA8Oa\", "
- "\"lv_name\":\"[thinpool_tdata]\"",
- "{\"lv_uuid\":\"<UUID: 5>\", \"lv_name\":\"[thinpool_tdata]\""},
- // Removable media paths.
- {"/media/removable/SD Card/", "/media/removable/<Volume Label: 2>/"},
- {"'/media/removable/My Secret Volume Name' don't redact this",
- "'/media/removable/<Volume Label: 3>' don't redact this"},
- {"0 part /media/removable/My Secret Volume Name With Spaces ",
- "0 part /media/removable/<Volume Label: 4>"},
- };
- for (const auto& p : test_cases) {
- EXPECT_EQ(redactor_.Redact(p.first), p.second);
- }
- }
- } // namespace feedback
|