#include "chrome/browser/ash/extensions/extensions_permissions_tracker.h"
#include "base/containers/fixed_flat_set.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "extensions/common/permissions/manifest_permission_set.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
namespace extensions {
namespace {
constexpr auto kManagedGuestSessionAllowlist = base::MakeFixedFlatSet<
std::string_view>({
"cbkkbcmdlboombapidmoeolnmdacpkch",
"inomeogfingihgjfjlpeplalcfajhgai",
"djflhoibgkdhkhhcedjiklpkjnoahfmg",
"iabmpiboiopbgfabjmgeedhcmjenhbla",
"haiffjcadagjlijoggckpgfnoeiflnem",
"lfnfbcjdepjffcaiagkdmlmiipelnfbb",
"mfaihdlpglflfgpfjcifdjdjcckigekc",
"ngjnkanfphagcaokhjecbgkboelgfcnf",
"cjanmonomjogheabiocdamfpknlpdehm",
"ioofdkhojeeimmagbjbknkejkgbphdfl",
"pmnllmkmjilbojkpgplbdmckghmaocjh",
"haeblkpifdemlfnkogkipmghfcbonief",
"mpnkhdpphjiihmlmkcamhpogecnnfffa",
"npilppbicblkkgjfnbmibmhhgjhobpll",
"ppkfnjlimknmjoaemnpidmdlfchhehel",
"aclofikceldphonlfmghmimkodjdmhck",
"eilbnahdgoddoedakcmfkcgfoegeloil",
"ceehlgckkmkaoggdnjhibffkphfnphmg",
"fnhgfoccpcjdnjcobejogdnlnidceemb",
"cmeclblmdmffdgpdlifgepjddoplmmal",
"bjfeaefhaooblkndnoabbkkkenknkemb",
"ehcabepphndocfmgbdkbjibfodelmpbb",
"kgimkbnclbekdkabkpjhpakhhalfanda",
"joodangkbfjnajiiifokapkpmhfnpleo",
"fpgfohogebplgnamlafljlcidjedbdeb",
"jkoildpomkimndcphjpffmephmcmkfhn",
"lbhdhapagjhalobandnbdnmblnmocojh",
"ielkookhdphmgbipcfmafkaiagademfp",
"kogjlbfgggambihdjcpijgcbmenblimd",
"ogbkmlkceflgpilgbmbcfbifckpkfacf",
"pbbbjjecobhljkkcenlakfnkmkfkfamd",
"jkbfjmnjcdmhlfpephomoiipbhcoiffb",
"dgmblbpgafgcgpkoiilhjifindhinmai",
"iggnealjakkgfofealilhkkclnbnfnmo",
"lplkobnahgbopmpkdapaihnnojkphahc",
"lejnflfhjpcannpaghnahbedlabpmhoh",
"dhjmfhojkfjmfbnbnpichdmcdghdpccg",
"ebkhfdfghngbimnpgelagnfacdafhaba",
"npnjdccdffhdndcbeappiamcehbhjibf",
"ekgadegabdkcbkodfbgidncffijbghhl",
"iddohohhpmajlkbejjjcfednjnhlnenk",
"bjdhhokmhgelphffoafoejjmlfblpdha",
"nldmakcnfaflagmohifhcihkfgcbmhph",
"mdhnphfgagkpdhndljccoackjjhghlif",
"dondgdlndnpianbklfnehgdhkickdjck",
"amfoiggnkefambnaaphodjdmdooiinna",
"fgjnkhlabjcaajddbaenilcmpcidahll",
"ifpkhncdnjfipfjlhfidljjffdgklanh",
"cgmlfbhkckbedohgdepgbkflommbfkep",
"ndlgnmfmgpdecjgehbcejboifbbmlkhp",
"edhhaiphkklkcfcbnlbpbiepchnkgkpn",
"jckncghadoodfbbbmbpldacojkooophh",
"diehajhcjifpahdplfdkhiboknagmfii",
"idneggepppginmaklfbaniklagjghpio",
"nhpmmldpbfjofkipjaieeomhnmcgihfm",
"kcjbmmhccecjokfmckhddpmghepcnidb",
"onbhgdmifjebcabplolilidlpgeknifi",
"kkkbcoabfhgekpnddfkaphobhinociem",
"adlphlfdhhjenpgimjochcpelbijkich",
"cgefhjmlaifaamhhoojmpcnihlbddeki",
"kpjjigggmcjinapdeipapdcnmnjealll",
"ifnadhpngkodeccijnalokiabanejfgm",
"klcojgagjmpgmffcildkgbfmfffncpcd",
"nnikmgjhdlphciaonjmoppfckbpoinnb",
"khldngaiohpnnoikfmnmfnebecgeobep",
"aleodiobpjillgfjdkblghiiaegggmcm",
"nifkmgcdokhkjghdlgflonppnefddien",
"hdmobeajeoanbanmdlabnbnlopepchip",
"ikmidginfdcbojdbmejkeakncgdbmonc",
"dgohlccohkojjgkkfholmobjjoledflp",
"dhmdaeekeihmajjnmichlhiffffdbpde",
"onklhlmbpfnmgmelakhgehkfdmkpmekd",
"jeabmjjifhfcejonjjhccaeigpnnjaak",
"gnckahkflocidcgjbeheneogeflpjien",
"pdckcbpciaaicoomipamcabpdadhofgh",
"biliocemfcghhioihldfdmkkhnofcgmb",
"bhfoghflalnnjfcfkaelngenjgjjhapk",
"pjckdjlmdcofkkkocnmhcbehkiapalho",
"pbdihpaifchmclcmkfdgffnnpfbobefh",
"lpmakjfjcconjeehbidjclhdlpjmfjjj",
"iggildboghmjpbjcpmobahnkmoefkike",
"elhbopodaklenjkeihkdhhfaghalllba",
"gjeelkjnolfmhphfhhjokaijbicopfln",
"mnoijifedipmbjaoekhadjcijipaijjc",
"gdobaoeekhiklaljmhladjfdfkigampc",
"lminefdanffajachfahfpmphfkhahcnj",
"fafhbhdboeiciklpkminlncemohljlkj",
"bnabjkecnachpogjlfilfcnlpcmacglh",
"ongnjlefhnoajpbodoldndkbkdgfomlp",
"ilnpadgckeacioehlommkaafedibdeob",
"oflckobdemeldmjddmlbaiaookhhcngo",
"behllobkkfkfnphdnhnkndlbkcpglgmj",
"mclkkofklkfljcocdinagocijmpgbhab",
"gbkeegbaiigmenfmjfclcdgdpimamgkj",
"aapbdbdomjkkjkaonfhkkikfgjllcleb",
"mgijmajocgfcbeboacabfgobmjgjcoja",
"mfhehppjhmmnlfbbopchdfldgimhfhfk",
"mkaakpdehdafacodkgkpghoibnmamcme",
"pnhechapfaindjhompbnflcldabbghjo",
"fcgckldmmjdbpdejkclmfnnnehhocbfp",
"jhknlonaankphkkbnmjdlpehkinifeeg",
"jndclpdbaamdhonoechobihbbiimdgai",
"aohghmighlieiainnegkcijnfilokake",
"eemlkeanncmjljgehlbplemhmdmalhdc",
"eoieeedlomnegifmaghhjnghhmcldobl",
"ndjpildffkeodjdaeebdhnncfhopkajk",
"pfoeakahkgllhkommkfeehmkfcloagkl",
"aapocclcgogkmnckokdopfmhonfmgoek",
"khpfeaanjngmcnplbdlpegiifgpfgdco",
"hmjkmjkepdijhoojdojkdfohbdgmmhki",
"felcaaldnbdncclmgdcncolpebgiejap",
"khkjfddibboofomnlkndfedpoccieiee",
"becloognjehhioodmnimnehjcibkloed",
"hfhhnacclhffhdffklopdkcgdhifgngh",
"adokjfanaflbkibffcbhihgihpgijcei",
"heildphpnddilhkemkielfhnkaagiabh",
"lpcaedmchfhocbbapmcbpinfpgnhiddi",
"ldipcbpaocekfooobnbcddclnhejkcpn",
"nnckehldicaciogcbchegobnafnjkcne",
"pfmgfdlgomnbgkofeojodiodmgpgmkac",
"djcfdncoelnlbldjfhinnjlhdjlikmph",
"ipkjmjaledkapilfdigkgfmpekpfnkih",
"kcnhkahnjcbndmmehfkdnkjomaanaooo",
"nlbjncdgjeocebhnmkbbbdekmmmcbfjd",
"aoggjnmghgmcllfenalipjhmooomfdce",
"fhndealchbngfhdoncgcokameljahhog",
"npeicpdbkakmehahjeeohfdhnlpdklia",
"hdkoikmfpncabbdniojdddokkomafcci",
});
}
bool IsAllowlistedForManagedGuestSession(const std::string& extension_id) {
return kManagedGuestSessionAllowlist.contains(extension_id);
}
ExtensionsPermissionsTracker::ExtensionsPermissionsTracker(
ExtensionRegistry* registry,
content::BrowserContext* browser_context)
: registry_(registry),
pref_service_(Profile::FromBrowserContext(browser_context)->GetPrefs()) {
observation_.Observe(registry_.get());
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(
pref_names::kInstallForceList,
base::BindRepeating(
&ExtensionsPermissionsTracker::OnForcedExtensionsPrefChanged,
base::Unretained(
this)));
OnForcedExtensionsPrefChanged();
}
ExtensionsPermissionsTracker::~ExtensionsPermissionsTracker() = default;
void ExtensionsPermissionsTracker::OnForcedExtensionsPrefChanged() {
const base::Value& value =
pref_service_->GetValue(pref_names::kInstallForceList);
if (!value.is_dict()) {
return;
}
extension_safety_ratings_.clear();
pending_forced_extensions_.clear();
for (const auto entry : value.GetDict()) {
const ExtensionId& extension_id = entry.first;
extension_safety_ratings_.insert(make_pair(extension_id, false));
const Extension* extension =
registry_->enabled_extensions().GetByID(extension_id);
if (extension)
ParseExtensionPermissions(extension);
else
pending_forced_extensions_.insert(extension_id);
}
if (pending_forced_extensions_.empty())
UpdateLocalState();
}
bool ExtensionsPermissionsTracker::IsSafePerms(
const PermissionsData* perms_data) const {
const PermissionSet& active_permissions = perms_data->active_permissions();
const APIPermissionSet& api_permissions = active_permissions.apis();
for (auto* permission : api_permissions) {
if (permission->info()->requires_managed_session_full_login_warning()) {
return false;
}
}
const ManifestPermissionSet& manifest_permissions =
active_permissions.manifest_permissions();
for (const auto* permission : manifest_permissions) {
if (permission->RequiresManagedSessionFullLoginWarning()) {
return false;
}
}
if (active_permissions.ShouldWarnAllHosts() ||
!active_permissions.effective_hosts().is_empty()) {
return false;
}
return true;
}
void ExtensionsPermissionsTracker::OnExtensionLoaded(
content::BrowserContext* browser_context,
const Extension* extension) {
auto itr = extension_safety_ratings_.find(extension->id());
if (itr == extension_safety_ratings_.end())
return;
pending_forced_extensions_.erase(extension->id());
ParseExtensionPermissions(extension);
if (!itr->second || pending_forced_extensions_.empty())
UpdateLocalState();
}
void ExtensionsPermissionsTracker::UpdateLocalState() {
bool any_unsafe = std::ranges::any_of(
extension_safety_ratings_,
[](const auto& key_value) { return !key_value.second; });
DCHECK(pending_forced_extensions_.empty() || any_unsafe);
g_browser_process->local_state()->SetBoolean(
prefs::kManagedSessionUseFullLoginWarning, any_unsafe);
}
void ExtensionsPermissionsTracker::RegisterLocalStatePrefs(
PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(prefs::kManagedSessionUseFullLoginWarning,
true);
}
void ExtensionsPermissionsTracker::ParseExtensionPermissions(
const Extension* extension) {
extension_safety_ratings_[extension->id()] =
IsAllowlistedForManagedGuestSession(extension->id()) ||
IsSafePerms(extension->permissions_data());
}
}