├── .gitignore
├── Cargo.toml
├── README.md
├── .github
└── workflows
│ └── rust.yml
├── list.txt
├── LICENSE.txt
├── src
└── main.rs
└── Cargo.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "check-extensions"
3 | version = "1.0.0"
4 | edition = "2021"
5 |
6 | [profile.release]
7 | panic = "abort"
8 | strip = true
9 | opt-level = "z"
10 | lto = true
11 | codegen-units = 1
12 |
13 | [dependencies]
14 | app_dirs2 = "2.5.5"
15 | enum-iterator = "1.4.1"
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Potentially malicious browser extensions
2 |
3 | I’ve been documenting lots of potentially malicious browser extensions in Chrome Web Store [[1]](https://palant.info/2023/05/31/more-malicious-extensions-in-chrome-web-store/) [[2]](https://palant.info/2023/06/05/introducing-pcvark-and-their-malicious-ad-blockers/) [[3]](https://palant.info/2023/06/08/another-cluster-of-potentially-malicious-chrome-extensions/). As the lists of affected extension IDs are getting long and difficult to keep track of, I decided to add them to this repository (see list.txt).
4 |
5 | Note: Some extensions listed are no longer available via Chrome Web Store. If they were installed prior to removal however, they often remain installed.
6 |
7 | ## Using check-extensions utility
8 |
9 | Instead of checking extension IDs against the list manually, you can also [download the check-extensions utility](https://github.com/palant/malicious-extensions-list/releases/). When run without parameters, it will try locating all browser profiles of Chrome and Chromium-based browsers under your user account. A list of browser profiles to check can also be given explicitly as command line parameters.
10 |
--------------------------------------------------------------------------------
/.github/workflows/rust.yml:
--------------------------------------------------------------------------------
1 | name: Rust
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | env:
10 | CARGO_TERM_COLOR: always
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ${{ matrix.os }}
16 |
17 | strategy:
18 | matrix:
19 | os: [ubuntu-latest, windows-latest, macos-latest]
20 | toolchain: [nightly-2023-04-16, stable]
21 | include:
22 | - toolchain: nightly-2023-04-16
23 | flags: -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort
24 | - toolchain: stable
25 | flags:
26 | - os: ubuntu-latest
27 | target: x86_64-unknown-linux-gnu
28 | target_name: check-extensions
29 | - os: windows-latest
30 | target: x86_64-pc-windows-msvc
31 | target_name: check-extensions.exe
32 | - os: macos-latest
33 | target: x86_64-apple-darwin
34 | target_name: check-extensions
35 | env:
36 | RUSTFLAGS:
37 |
38 | steps:
39 | - uses: actions/checkout@v3
40 | - name: Install toolchain
41 | uses: actions-rust-lang/setup-rust-toolchain@v1
42 | with:
43 | toolchain: ${{ matrix.toolchain }}
44 | components: rust-src
45 | - name: Build
46 | run: cargo +${{ matrix.toolchain }} build ${{ matrix.flags }} --target ${{ matrix.target }} --release --verbose
47 | - name: Upload check-extensions artifact
48 | uses: actions/upload-artifact@v3
49 | with:
50 | name: ${{ matrix.target_name }} ${{ matrix.os }} ${{ matrix.toolchain }}
51 | path: target/${{ matrix.target }}/release/${{ matrix.target_name }}
52 |
--------------------------------------------------------------------------------
/list.txt:
--------------------------------------------------------------------------------
1 | # https://palant.info/2023/05/31/more-malicious-extensions-in-chrome-web-store/
2 | lgjdgmdbfhobkdbcjnpnlmhnplnidkkp
3 | chmfnmjfghjpdamlofhlonnnnokkpbao
4 | lklmhefoneonjalpjcnhaidnodopinib
5 | ciifcakemmcbbdpmljdohdmbodagmela
6 | meljmedplehjlnnaempfdoecookjenph
7 | lipmdblppejomolopniipdjlpfjcojob
8 | lmcboojgmmaafdmgacncdpjnpnnhpmei
9 | icnekagcncdgpdnpoecofjinkplbnocm
10 | bahogceckgcanpcoabcdgmoidngedmfo
11 | bkpdalonclochcahhipekbnedhklcdnp
12 | magnkhldhhgdlhikeighmhlhonpmlolk
13 | edadmcnnkkkgmofibeehgaffppadbnbi
14 | ajneghihjbebmnljfhlpdmjjpifeaokc
15 | nadenkhojomjfdcppbhhncbfakfjiabp
16 | pbdpfhmbdldfoioggnphkiocpidecmbp
17 | hdgdghnfcappcodemanhafioghjhlbpb
18 | fbjfihoienmhbjflbobnmimfijpngkpa
19 | kjeffohcijbnlkgoaibmdcfconakaajm
20 | djmpbcihmblfdlkcfncodakgopmpgpgh
21 | obeokabcpoilgegepbhlcleanmpgkhcp
22 | mcmdolplhpeopapnlpbjceoofpgmkahc
23 | dppnhoaonckcimpejpjodcdoenfjleme
24 | idgncaddojiejegdmkofblgplkgmeipk
25 | deebfeldnfhemlnidojiiidadkgnglpi
26 | gfbgiekofllpkpaoadjhbbfnljbcimoh
27 | pbebadpeajadcmaoofljnnfgofehnpeo
28 | flmihfcdcgigpfcfjpdcniidbfnffdcf
29 | pinnfpbpjancnbidnnhpemakncopaega
30 | iicpikopjmmincpjkckdngpkmlcchold
31 | bjlcpoknpgaoaollojjdnbdojdclidkh
32 | okclicinnbnfkgchommiamjnkjcibfid
33 | pcjmcnhpobkjnhajhhleejfmpeoahclc
34 | hinhmojdkodmficpockledafoeodokmc
35 | gcnceeflimggoamelclcbhcdggcmnglm
36 |
37 | # https://palant.info/2023/06/05/introducing-pcvark-and-their-malicious-ad-blockers/
38 | kacljcbejojnapnmiifgckbafkojcncf
39 | jhkhlgaomejplkanglolfpcmfknnomle
40 | nkmooloiipfcknccapehflmampkaniji
41 | kgddnoifhgfdhcpbkkjdgokfnkkmdcen
42 |
43 | # https://palant.info/2023/06/08/another-cluster-of-potentially-malicious-chrome-extensions/
44 | gbdjcgalliefpinpmggefbloehmmknca
45 | eggeoellnjnnglaibpcmggjnjifeebpi
46 | ionpbgeeliajehajombdeflogfpgmmel
47 | jaekigmcljkkalnicnjoafgfjoefkpeg
48 | aeilijiaejfdnbagnpannhdoaljpkbhe
49 | afdfpkhbdpioonfeknablodaejkklbdn
50 | anflghppebdhjipndogapfagemgnlblh
51 | anmbbeeiaollmpadookgoakpfjkbidaf
52 | bebmphofpgkhclocdbgomhnjcpelbenh
53 | bmkgbgkneealfabgnjfeljaiegpginpl
54 | ccjlpblmgkncnnimcmbanbnhbggdpkie
55 | cclhgechkjghfaoebihpklmllnnlnbdb
56 | cfegchignldpfnjpodhcklmgleaoanhi
57 | cfllfglbkmnbkcibbjoghimalbileaic
58 | cjljdgfhkjbdbkcdkfojleidpldagmao
59 | coabfkgengacobjpmdlmmihhhfnhbjdm
60 | dcaffjpclkkjfacgfofgpjbmgjnjlpmh
61 | djekgpcemgcnfkjldcclcpcjhemofcib
62 | dkbccihpiccbcheieabdbjikohfdfaje
63 | dlpimjmonhbmamocpboifndnnakgknbf
64 | dmbjkidogjmmlejdmnecpmfapdmidfjg
65 | dneifdhdmnmmlobjbimlkcnhkbidmlek
66 | doiiaejbgndnnnomcdhefcbfnbbjfbib
67 | dpfofggmkhdbfcciajfdphofclabnogo
68 | eabhkjojehdleajkbigffmpnaelncapp
69 | ealojglnbikknifbgleaceopepceakfn
70 | ebdbcfomjliacpblnioignhfhjeajpch
71 | edlifbnjlicfpckhgjhflgkeeibhhcii
72 | ehmneimbopigfgchjglgngamiccjkijh
73 | ehpgcagmhpndkmglombjndkdmggkgnge
74 | ejllkedmklophclpgonojjkaliafeilj
75 | ekjogkoigkhbgdgpolejnjfmhdcgaoof
76 | elpdbicokgbedckgblmbhoamophfbchi
77 | emeokgokialpjadjaoeiplmnkjoaegng
78 | eokjikchkppnkdipbiggnmlkahcdkikp
79 | epeigjgefhajkiiallmfblgglmdbhfab
80 | eplfglplnlljjpeiccbgnijecmkeimed
81 | fbbjijdngocdplimineplmdllhjkaece
82 | fbjhgeaafhlbjiejehpjdnghinlcceak
83 | fedchalbmgfhdobblebblldiblbmpgdj
84 | fobaamfiblkoobhjpiigemmdegbmpohd
85 | gaiceihehajjahakcglkhmdbbdclbnlf
86 | gceehiicnbpehbbdaloolaanlnddailm
87 | ggacghlcchiiejclfdajbpkbjfgjhfol
88 | gjjbmfigjpgnehjioicaalopaikcnheo
89 | gpdfpljioapjogbnlpmganakfjcemifk
90 | hjlekdknhjogancdagnndeenmobeofgm
91 | hlbdhflagoegglpdminhlpenkdgloabe
92 | hnfabcchmopgohnhkcojhocneefbnffg
93 | iabflonngmpkalkpbjonemaamlgdghea
94 | ibppednjgooiepmkgdcoppnmbhmieefh
95 | icchadngbpkcegnabnabhkjkfkfflmpj
96 | ielooaepfhfcnmihgnabkldnpddnnldl
97 | ifdepgnnjpnbkcgempionjablajancjc
98 | ijejnggjjphlenbhmjhhgcdpehhacaal
99 | iklgljbighkgbjoecoddejooldolenbj
100 | imopknpgdihifjkjpmjaagcagkefddnb
101 | jchmabokofdoabocpiicjljelmackhho
102 | jdlkkmamiaikhfampledjnhhkbeifokk
103 | jglemppahimembneahjbkhjknnefeeio
104 | jiaopkfkampgnnkckajcbdgannoipcne
105 | jjgnkfncaadmaobenjjpmngdpgalemho
106 | jlbpahgopcmomkgegpbmopfodolajhbl
107 | jpefmbpcbebpjpmelobfakahfdcgcmkl
108 | khdnaopfklkdcloiinccnaflffmfcioa
109 | kjgkmceledmpdnmgmppiekdbnamccdjp
110 | laameccjpleogmfhilmffpdbiibgbekf
111 | lagdcjmbchphhndlbpfajelapcodekll
112 | lbohagbplppjcpllnhdichjldhfgkicb
113 | ledkggjjapdgojgihnaploncccgiadhg
114 | lgecddhfcfhlmllljooldkbbijdcnlpe
115 | lkahpjghmdhpiojknppmlenngmpkkfma
116 | lkciiknpgglgbbcgcpbpobjabglmpkle
117 | lkhhagecaghfakddbncibijbjmgfhfdm
118 | lknpbgnookklokdjomiildnlalffjmma
119 | lojpdfjjionbhgplcangflkalmiadhfi
120 | mdkiofbiinbmlblcfhfjgmclhdfikkpm
121 | meffljleomgifbbcffejnmhjagncfpbd
122 | mejjgaogggabifjfjdbnobinfibaamla
123 | mhpcabliilgadobjpkameggapnpeppdg
124 | mkjjckchdfhjbpckippbnipkdnlidbeb
125 | mldaiedoebimcgkokmknonjefkionldi
126 | mlkjjjmhjijlmafgjlpkiobpdocdbncj
127 | mndiaaeaiclnmjcnacogaacoejchdclp
128 | mnlohknjofogcljbcknkakphddjpijak
129 | nhnfcgpcbfclhfafjlooihdfghaeinfc
130 | ninecedhhpccjifamhafbdelibdjibgd
131 | nmigaijibiabddkkmjhlehchpmgbokfj
132 | npdkkcjlmhcnnaoobfdjndibfkkhhdfn
133 | npmjjkphdlmbeidbdbfefgedondknlaf
134 | oakbcaafbicdddpdlhbchhpblmhefngh
135 | obdhcplpbliifflekgclobogbdliddjd
136 | ocginjipilabheemhfbedijlhajbcabh
137 | oepjogknopbbibcjcojmedaepolkghpb
138 | ofpnikijgfhlmmjlpkfaifhhdonchhoi
139 | ogadflejmplcdhcldlloonbiekhnlopp
140 | ogfjgagnmkiigilnoiabkbbajinanlbn
141 | okkffdhbfplmbjblhgapnchjinanmnij
142 | oodkhhminilgphkdofffddlgopkgbgpm
143 | pegfdldddiilihjahcpdehhhfcbibipg
144 | phfkifnjcmdcmljnnablahicoabkokbg
145 | phjbepamfhjgjdgmbhmfflhnlohldchb
146 | pjbgfifennfhnbkhoidkdchbflppjncb
147 | plmlopfeeobajiecodiggabcihohcnge
148 | pmilcmjbofinpnbnpanpdadijibcgifc
149 | pmnphobdokkajkpbkajlaiooipfcpgio
150 | pnanegnllonoiklmmlegcaajoicfifcm
151 | pnlphjjfielecalmmjjdhjjninkbjdod
152 | pooaemmkohlphkekccfajnbcokjlbehk
153 |
154 | # https://palant.info/2023/06/08/another-cluster-of-potentially-malicious-chrome-extensions/#c000003
155 | fmlpbbognkocpajihchioognkmdeeldo
156 | goaebigflkhjjblmofhoggdhebgnielo
157 | igkkmokkmlbkkgdnkkancbonkbbmkioc
158 | lopnbnfpjmgpbppclhclehhgafnifija
159 |
160 | # https://palant.info/2023/06/14/why-browser-extension-games-need-access-to-all-websites/
161 | kgfeiebnfmmfpomhochmlfmdmjmfedfj
162 | pmlcjncilaaaemknfefmegedhcgelmee
163 | ohdgnoepeabcfdkboidmaedenahioohf
164 | dnbipceilikdgjmeiagblfckeialaela
165 | aciipkgmbljbcokcnhjbjdhilpngemnj
166 | nlmjpeojbncdmlfkpppngdnolhfgiehn
167 | phjhbkdgnjaokligmkimgnlagccanodn
168 | fkhpfgpmejefmjaeelgoopkcglgafedm
169 | kekdpkbijjffmohdaonbpeeaiknhbkhj
170 | mcmmiinopedfbaoongoclagidncaacbd
171 | ndcokkmfmiaecmndbpohaogmpmchfpkk
172 | cpmpjapeeidaikiiemnddfgfdfjjhgif
173 | ajefbooiifdkmgkpjkanmgbjbndfbfhg
174 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
117 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | #![deny(elided_lifetimes_in_paths)]
2 | #![deny(explicit_outlives_requirements)]
3 | #![deny(keyword_idents)]
4 | #![deny(meta_variable_misuse)]
5 | #![deny(missing_debug_implementations)]
6 | #![deny(non_ascii_idents)]
7 | #![warn(noop_method_call)]
8 | #![deny(pointer_structural_match)]
9 | #![deny(single_use_lifetimes)]
10 | #![deny(trivial_casts)]
11 | #![deny(trivial_numeric_casts)]
12 | #![deny(unsafe_code)]
13 | #![warn(unused_crate_dependencies)]
14 | #![deny(unused_import_braces)]
15 | #![deny(unused_lifetimes)]
16 | #![warn(unused_macro_rules)]
17 | #![warn(unused_tuple_struct_fields)]
18 | #![deny(variant_size_differences)]
19 |
20 | use std::collections::HashMap;
21 | use std::path::{Path, PathBuf};
22 |
23 | use enum_iterator::Sequence;
24 |
25 | #[derive(Debug, Sequence)]
26 | enum Browser {
27 | Chrome,
28 | ChromeBeta,
29 | ChromeCanary,
30 | Chromium,
31 | Opera,
32 | OperaBeta,
33 | OperaDev,
34 | Vivaldi,
35 | VivaldiSnapshot,
36 | Edge,
37 | EdgeBeta,
38 | EdgeDev,
39 | EdgeCanary,
40 | }
41 |
42 | impl Browser {
43 | #[cfg(target_os = "linux")]
44 | pub fn get_profile_root(self) -> Option {
45 | let mut dir = app_dirs2::get_data_root(app_dirs2::AppDataType::UserConfig).ok()?;
46 | match self {
47 | // https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md#Default-Location
48 | Self::Chrome => dir.push("google-chrome"),
49 | Self::ChromeBeta => dir.push("google-chrome-beta"),
50 | Self::ChromeCanary => dir.push("google-chrome-unstable"),
51 | Self::Chromium => dir.push("chromium"),
52 | Self::Opera => dir.push("opera"),
53 | Self::OperaBeta => dir.push("opera-beta"),
54 | Self::OperaDev => dir.push("opera-developer"),
55 | // https://help.vivaldi.com/desktop/privacy/preventing-vivaldi-profiles-from-being-uploaded-to-git-repositories/
56 | Self::Vivaldi => dir.push("vivaldi"),
57 | Self::VivaldiSnapshot => dir.push("vivaldi-snapshot"),
58 | Self::Edge => dir.push("microsoft-edge"),
59 | Self::EdgeBeta => dir.push("microsoft-edge-beta"),
60 | Self::EdgeDev => dir.push("microsoft-edge-dev"),
61 | Self::EdgeCanary => dir.push("microsoft-edge-unstable"),
62 | }
63 | Some(dir)
64 | }
65 |
66 | #[cfg(target_os = "windows")]
67 | pub fn get_profile_root(self) -> Option {
68 | let mut dir = app_dirs2::get_data_root(app_dirs2::AppDataType::UserData).ok()?;
69 | match self {
70 | Self::Chrome => {
71 | dir.push("Google");
72 | dir.push("Chrome");
73 | }
74 | Self::ChromeBeta => {
75 | dir.push("Google");
76 | dir.push("Chrome Beta");
77 | }
78 | Self::ChromeCanary => {
79 | dir.push("Google");
80 | dir.push("Chrome SxS");
81 | }
82 | Self::Chromium => dir.push("Chromium"),
83 | Self::Opera => dir.push("Opera"),
84 | Self::OperaBeta => dir.push("Opera Beta"),
85 | Self::OperaDev => dir.push("Opera Developer"),
86 | Self::Vivaldi => dir.push("Vivaldi"),
87 | Self::VivaldiSnapshot => dir.push("Vivaldi Snapshot"),
88 | Self::Edge => {
89 | dir.push("Microsoft");
90 | dir.push("Edge");
91 | }
92 | Self::EdgeBeta => {
93 | dir.push("Microsoft");
94 | dir.push("Edge Beta");
95 | }
96 | Self::EdgeDev => {
97 | dir.push("Microsoft");
98 | dir.push("Edge Dev");
99 | }
100 | Self::EdgeCanary => {
101 | dir.push("Microsoft");
102 | dir.push("Edge SxS");
103 | }
104 | }
105 | dir.push("User Data");
106 | Some(dir)
107 | }
108 |
109 | #[cfg(target_os = "macos")]
110 | pub fn get_profile_root(self) -> Option {
111 | let mut dir = app_dirs2::get_data_root(app_dirs2::AppDataType::UserData).ok()?;
112 | match self {
113 | Self::Chrome => {
114 | dir.push("Google");
115 | dir.push("Chrome");
116 | }
117 | Self::ChromeBeta => {
118 | dir.push("Google");
119 | dir.push("Chrome Beta");
120 | }
121 | Self::ChromeCanary => {
122 | dir.push("Google");
123 | dir.push("Chrome Canary");
124 | }
125 | Self::Chromium => dir.push("Chromium"),
126 | Self::Opera => dir.push("Opera"),
127 | Self::OperaBeta => dir.push("Opera Beta"),
128 | Self::OperaDev => dir.push("Opera Developer"),
129 | Self::Vivaldi => dir.push("Vivaldi"),
130 | Self::VivaldiSnapshot => dir.push("Vivaldi Snapshot"),
131 | Self::Edge => dir.push("Microsoft Edge"),
132 | Self::EdgeBeta => dir.push("Microsoft Edge Beta"),
133 | Self::EdgeDev => dir.push("Microsoft Edge Dev"),
134 | Self::EdgeCanary => dir.push("Microsoft Edge Canary"),
135 | }
136 | Some(dir)
137 | }
138 | }
139 |
140 | fn get_ids() -> HashMap {
141 | const DATA: &str = include_str!("../list.txt");
142 | let mut current_url = String::new();
143 | let mut result = HashMap::new();
144 | for line in DATA.split(['\r', '\n']) {
145 | if line.is_empty() {
146 | continue;
147 | }
148 |
149 | if let Some(url) = line.strip_prefix('#') {
150 | current_url = url.trim().to_string();
151 | } else {
152 | result.insert(line.trim().to_string(), current_url.clone());
153 | }
154 | }
155 | result
156 | }
157 |
158 | fn is_profile(path: &Path) -> bool {
159 | if path.is_dir() {
160 | let mut preferences = path.to_path_buf();
161 | preferences.push("Preferences");
162 | preferences.is_file()
163 | } else {
164 | false
165 | }
166 | }
167 |
168 | fn get_profiles() -> Vec {
169 | let mut result = Vec::new();
170 | for root in enum_iterator::all().filter_map(Browser::get_profile_root) {
171 | let entries = match root.read_dir() {
172 | Ok(entries) => entries,
173 | Err(_) => continue,
174 | };
175 |
176 | result.extend(
177 | entries
178 | .filter_map(|entry| entry.ok())
179 | .map(|entry| entry.path())
180 | .filter(|path| is_profile(path)),
181 | );
182 | if is_profile(&root) {
183 | result.push(root);
184 | }
185 | }
186 | result
187 | }
188 |
189 | fn main() {
190 | let args = std::env::args_os().collect::>();
191 |
192 | let profiles = if args.len() > 1 {
193 | let mut paths = Vec::new();
194 | for arg in &args[1..] {
195 | let path = PathBuf::from(arg);
196 | if is_profile(&path) {
197 | paths.push(path);
198 | } else {
199 | eprintln!("{} does not seem to be a browser profile, is it the directory containing Preferences file?", arg.to_string_lossy());
200 | }
201 | }
202 |
203 | if paths.is_empty() {
204 | eprintln!("No valid browser profiles given.");
205 | return;
206 | }
207 | paths
208 | } else {
209 | get_profiles()
210 | };
211 |
212 | if profiles.is_empty() {
213 | eprintln!("No browser profiles found, try passing a directory on command line explicitly.");
214 | return;
215 | }
216 |
217 | let ids = get_ids();
218 | for path in profiles {
219 | eprintln!("Checking profile {}", path.as_os_str().to_string_lossy());
220 |
221 | let mut extensions = path.clone();
222 | extensions.push("Extensions");
223 |
224 | let mut seen_extension = false;
225 | let mut seen_malicious = false;
226 | if let Ok(entries) = extensions.read_dir() {
227 | for entry in entries.filter_map(|entry| entry.ok()) {
228 | seen_extension = true;
229 | let name = entry.file_name();
230 | let id = name.to_string_lossy();
231 | if let Some(url) = ids.get(id.as_ref()) {
232 | eprintln!("Extension {id} is potentially malicious, see {url}");
233 | seen_malicious = true;
234 | }
235 | }
236 | }
237 |
238 | if !seen_extension {
239 | eprintln!("Unable to find any extensions for this browser.");
240 | } else if !seen_malicious {
241 | eprintln!("No malicious extensions found.");
242 | }
243 |
244 | eprintln!();
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "app_dirs2"
7 | version = "2.5.5"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "a7e7b35733e3a8c1ccb90385088dd5b6eaa61325cb4d1ad56e683b5224ff352e"
10 | dependencies = [
11 | "jni",
12 | "ndk-context",
13 | "winapi",
14 | "xdg",
15 | ]
16 |
17 | [[package]]
18 | name = "bytes"
19 | version = "1.4.0"
20 | source = "registry+https://github.com/rust-lang/crates.io-index"
21 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
22 |
23 | [[package]]
24 | name = "cesu8"
25 | version = "1.1.0"
26 | source = "registry+https://github.com/rust-lang/crates.io-index"
27 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
28 |
29 | [[package]]
30 | name = "cfg-if"
31 | version = "1.0.0"
32 | source = "registry+https://github.com/rust-lang/crates.io-index"
33 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
34 |
35 | [[package]]
36 | name = "check-extensions"
37 | version = "1.0.0"
38 | dependencies = [
39 | "app_dirs2",
40 | "enum-iterator",
41 | ]
42 |
43 | [[package]]
44 | name = "combine"
45 | version = "4.6.6"
46 | source = "registry+https://github.com/rust-lang/crates.io-index"
47 | checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
48 | dependencies = [
49 | "bytes",
50 | "memchr",
51 | ]
52 |
53 | [[package]]
54 | name = "enum-iterator"
55 | version = "1.4.1"
56 | source = "registry+https://github.com/rust-lang/crates.io-index"
57 | checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689"
58 | dependencies = [
59 | "enum-iterator-derive",
60 | ]
61 |
62 | [[package]]
63 | name = "enum-iterator-derive"
64 | version = "1.2.1"
65 | source = "registry+https://github.com/rust-lang/crates.io-index"
66 | checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb"
67 | dependencies = [
68 | "proc-macro2",
69 | "quote",
70 | "syn",
71 | ]
72 |
73 | [[package]]
74 | name = "home"
75 | version = "0.5.5"
76 | source = "registry+https://github.com/rust-lang/crates.io-index"
77 | checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
78 | dependencies = [
79 | "windows-sys 0.48.0",
80 | ]
81 |
82 | [[package]]
83 | name = "jni"
84 | version = "0.21.1"
85 | source = "registry+https://github.com/rust-lang/crates.io-index"
86 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
87 | dependencies = [
88 | "cesu8",
89 | "cfg-if",
90 | "combine",
91 | "jni-sys",
92 | "log",
93 | "thiserror",
94 | "walkdir",
95 | "windows-sys 0.45.0",
96 | ]
97 |
98 | [[package]]
99 | name = "jni-sys"
100 | version = "0.3.0"
101 | source = "registry+https://github.com/rust-lang/crates.io-index"
102 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
103 |
104 | [[package]]
105 | name = "log"
106 | version = "0.4.19"
107 | source = "registry+https://github.com/rust-lang/crates.io-index"
108 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
109 |
110 | [[package]]
111 | name = "memchr"
112 | version = "2.5.0"
113 | source = "registry+https://github.com/rust-lang/crates.io-index"
114 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
115 |
116 | [[package]]
117 | name = "ndk-context"
118 | version = "0.1.1"
119 | source = "registry+https://github.com/rust-lang/crates.io-index"
120 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
121 |
122 | [[package]]
123 | name = "proc-macro2"
124 | version = "1.0.60"
125 | source = "registry+https://github.com/rust-lang/crates.io-index"
126 | checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
127 | dependencies = [
128 | "unicode-ident",
129 | ]
130 |
131 | [[package]]
132 | name = "quote"
133 | version = "1.0.28"
134 | source = "registry+https://github.com/rust-lang/crates.io-index"
135 | checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
136 | dependencies = [
137 | "proc-macro2",
138 | ]
139 |
140 | [[package]]
141 | name = "same-file"
142 | version = "1.0.6"
143 | source = "registry+https://github.com/rust-lang/crates.io-index"
144 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
145 | dependencies = [
146 | "winapi-util",
147 | ]
148 |
149 | [[package]]
150 | name = "syn"
151 | version = "2.0.18"
152 | source = "registry+https://github.com/rust-lang/crates.io-index"
153 | checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
154 | dependencies = [
155 | "proc-macro2",
156 | "quote",
157 | "unicode-ident",
158 | ]
159 |
160 | [[package]]
161 | name = "thiserror"
162 | version = "1.0.40"
163 | source = "registry+https://github.com/rust-lang/crates.io-index"
164 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
165 | dependencies = [
166 | "thiserror-impl",
167 | ]
168 |
169 | [[package]]
170 | name = "thiserror-impl"
171 | version = "1.0.40"
172 | source = "registry+https://github.com/rust-lang/crates.io-index"
173 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
174 | dependencies = [
175 | "proc-macro2",
176 | "quote",
177 | "syn",
178 | ]
179 |
180 | [[package]]
181 | name = "unicode-ident"
182 | version = "1.0.9"
183 | source = "registry+https://github.com/rust-lang/crates.io-index"
184 | checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
185 |
186 | [[package]]
187 | name = "walkdir"
188 | version = "2.3.3"
189 | source = "registry+https://github.com/rust-lang/crates.io-index"
190 | checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
191 | dependencies = [
192 | "same-file",
193 | "winapi-util",
194 | ]
195 |
196 | [[package]]
197 | name = "winapi"
198 | version = "0.3.9"
199 | source = "registry+https://github.com/rust-lang/crates.io-index"
200 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
201 | dependencies = [
202 | "winapi-i686-pc-windows-gnu",
203 | "winapi-x86_64-pc-windows-gnu",
204 | ]
205 |
206 | [[package]]
207 | name = "winapi-i686-pc-windows-gnu"
208 | version = "0.4.0"
209 | source = "registry+https://github.com/rust-lang/crates.io-index"
210 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
211 |
212 | [[package]]
213 | name = "winapi-util"
214 | version = "0.1.5"
215 | source = "registry+https://github.com/rust-lang/crates.io-index"
216 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
217 | dependencies = [
218 | "winapi",
219 | ]
220 |
221 | [[package]]
222 | name = "winapi-x86_64-pc-windows-gnu"
223 | version = "0.4.0"
224 | source = "registry+https://github.com/rust-lang/crates.io-index"
225 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
226 |
227 | [[package]]
228 | name = "windows-sys"
229 | version = "0.45.0"
230 | source = "registry+https://github.com/rust-lang/crates.io-index"
231 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
232 | dependencies = [
233 | "windows-targets 0.42.2",
234 | ]
235 |
236 | [[package]]
237 | name = "windows-sys"
238 | version = "0.48.0"
239 | source = "registry+https://github.com/rust-lang/crates.io-index"
240 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
241 | dependencies = [
242 | "windows-targets 0.48.0",
243 | ]
244 |
245 | [[package]]
246 | name = "windows-targets"
247 | version = "0.42.2"
248 | source = "registry+https://github.com/rust-lang/crates.io-index"
249 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
250 | dependencies = [
251 | "windows_aarch64_gnullvm 0.42.2",
252 | "windows_aarch64_msvc 0.42.2",
253 | "windows_i686_gnu 0.42.2",
254 | "windows_i686_msvc 0.42.2",
255 | "windows_x86_64_gnu 0.42.2",
256 | "windows_x86_64_gnullvm 0.42.2",
257 | "windows_x86_64_msvc 0.42.2",
258 | ]
259 |
260 | [[package]]
261 | name = "windows-targets"
262 | version = "0.48.0"
263 | source = "registry+https://github.com/rust-lang/crates.io-index"
264 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
265 | dependencies = [
266 | "windows_aarch64_gnullvm 0.48.0",
267 | "windows_aarch64_msvc 0.48.0",
268 | "windows_i686_gnu 0.48.0",
269 | "windows_i686_msvc 0.48.0",
270 | "windows_x86_64_gnu 0.48.0",
271 | "windows_x86_64_gnullvm 0.48.0",
272 | "windows_x86_64_msvc 0.48.0",
273 | ]
274 |
275 | [[package]]
276 | name = "windows_aarch64_gnullvm"
277 | version = "0.42.2"
278 | source = "registry+https://github.com/rust-lang/crates.io-index"
279 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
280 |
281 | [[package]]
282 | name = "windows_aarch64_gnullvm"
283 | version = "0.48.0"
284 | source = "registry+https://github.com/rust-lang/crates.io-index"
285 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
286 |
287 | [[package]]
288 | name = "windows_aarch64_msvc"
289 | version = "0.42.2"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
292 |
293 | [[package]]
294 | name = "windows_aarch64_msvc"
295 | version = "0.48.0"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
298 |
299 | [[package]]
300 | name = "windows_i686_gnu"
301 | version = "0.42.2"
302 | source = "registry+https://github.com/rust-lang/crates.io-index"
303 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
304 |
305 | [[package]]
306 | name = "windows_i686_gnu"
307 | version = "0.48.0"
308 | source = "registry+https://github.com/rust-lang/crates.io-index"
309 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
310 |
311 | [[package]]
312 | name = "windows_i686_msvc"
313 | version = "0.42.2"
314 | source = "registry+https://github.com/rust-lang/crates.io-index"
315 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
316 |
317 | [[package]]
318 | name = "windows_i686_msvc"
319 | version = "0.48.0"
320 | source = "registry+https://github.com/rust-lang/crates.io-index"
321 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
322 |
323 | [[package]]
324 | name = "windows_x86_64_gnu"
325 | version = "0.42.2"
326 | source = "registry+https://github.com/rust-lang/crates.io-index"
327 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
328 |
329 | [[package]]
330 | name = "windows_x86_64_gnu"
331 | version = "0.48.0"
332 | source = "registry+https://github.com/rust-lang/crates.io-index"
333 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
334 |
335 | [[package]]
336 | name = "windows_x86_64_gnullvm"
337 | version = "0.42.2"
338 | source = "registry+https://github.com/rust-lang/crates.io-index"
339 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
340 |
341 | [[package]]
342 | name = "windows_x86_64_gnullvm"
343 | version = "0.48.0"
344 | source = "registry+https://github.com/rust-lang/crates.io-index"
345 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
346 |
347 | [[package]]
348 | name = "windows_x86_64_msvc"
349 | version = "0.42.2"
350 | source = "registry+https://github.com/rust-lang/crates.io-index"
351 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
352 |
353 | [[package]]
354 | name = "windows_x86_64_msvc"
355 | version = "0.48.0"
356 | source = "registry+https://github.com/rust-lang/crates.io-index"
357 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
358 |
359 | [[package]]
360 | name = "xdg"
361 | version = "2.5.0"
362 | source = "registry+https://github.com/rust-lang/crates.io-index"
363 | checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee"
364 | dependencies = [
365 | "home",
366 | ]
367 |
--------------------------------------------------------------------------------