page_info.cc 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/page_info/page_info.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/i18n/time_formatting.h"
  12. #include "base/metrics/field_trial.h"
  13. #include "base/metrics/histogram_functions.h"
  14. #include "base/metrics/user_metrics.h"
  15. #include "base/strings/string_number_conversions.h"
  16. #include "base/strings/utf_string_conversions.h"
  17. #include "base/values.h"
  18. #include "build/build_config.h"
  19. #include "components/browser_ui/util/android/url_constants.h"
  20. #include "components/browsing_data/content/local_storage_helper.h"
  21. #include "components/content_settings/browser/page_specific_content_settings.h"
  22. #include "components/content_settings/core/browser/content_settings_registry.h"
  23. #include "components/content_settings/core/browser/content_settings_utils.h"
  24. #include "components/content_settings/core/browser/host_content_settings_map.h"
  25. #include "components/content_settings/core/common/content_settings.h"
  26. #include "components/content_settings/core/common/content_settings_pattern.h"
  27. #include "components/content_settings/core/common/content_settings_utils.h"
  28. #include "components/page_info/page_info_delegate.h"
  29. #include "components/page_info/page_info_ui.h"
  30. #include "components/password_manager/core/browser/password_manager_metrics_util.h"
  31. #include "components/permissions/object_permission_context_base.h"
  32. #include "components/permissions/permission_decision_auto_blocker.h"
  33. #include "components/permissions/permission_manager.h"
  34. #include "components/permissions/permission_result.h"
  35. #include "components/permissions/permission_uma_util.h"
  36. #include "components/permissions/permission_util.h"
  37. #include "components/permissions/permissions_client.h"
  38. #if BUILDFLAG(IS_ANDROID)
  39. #include "components/resources/android/theme_resources.h"
  40. #endif
  41. #include "build/chromeos_buildflags.h"
  42. #include "components/page_info/core/features.h"
  43. #include "components/privacy_sandbox/privacy_sandbox_features.h"
  44. #include "components/safe_browsing/buildflags.h"
  45. #include "components/safe_browsing/content/browser/password_protection/password_protection_service.h"
  46. #include "components/safe_browsing/core/browser/password_protection/metrics_util.h"
  47. #include "components/safe_browsing/core/common/proto/csd.pb.h"
  48. #include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
  49. #include "components/signin/public/identity_manager/account_info.h"
  50. #include "components/ssl_errors/error_info.h"
  51. #include "components/strings/grit/components_chromium_strings.h"
  52. #include "components/strings/grit/components_strings.h"
  53. #include "components/subresource_filter/core/browser/subresource_filter_features.h"
  54. #include "components/url_formatter/elide_url.h"
  55. #include "content/public/browser/browser_context.h"
  56. #include "content/public/browser/browser_thread.h"
  57. #include "content/public/common/content_features.h"
  58. #include "content/public/common/url_constants.h"
  59. #include "net/cert/cert_status_flags.h"
  60. #include "net/cert/x509_certificate.h"
  61. #include "net/ssl/ssl_cipher_suite_names.h"
  62. #include "net/ssl/ssl_connection_status_flags.h"
  63. #include "services/metrics/public/cpp/ukm_builders.h"
  64. #include "services/metrics/public/cpp/ukm_recorder.h"
  65. #include "third_party/boringssl/src/include/openssl/ssl.h"
  66. #include "ui/base/l10n/l10n_util.h"
  67. #include "url/origin.h"
  68. using base::ASCIIToUTF16;
  69. using base::UTF16ToUTF8;
  70. using base::UTF8ToUTF16;
  71. using content::BrowserThread;
  72. using safe_browsing::LoginReputationClientResponse;
  73. using safe_browsing::RequestOutcome;
  74. namespace {
  75. // The list of content settings types to display on the Page Info UI. THE
  76. // ORDER OF THESE ITEMS IS IMPORTANT and comes from https://crbug.com/610358. To
  77. // propose changing it, email security-dev@chromium.org.
  78. ContentSettingsType kPermissionType[] = {
  79. ContentSettingsType::GEOLOCATION,
  80. ContentSettingsType::MEDIASTREAM_CAMERA,
  81. ContentSettingsType::CAMERA_PAN_TILT_ZOOM,
  82. ContentSettingsType::MEDIASTREAM_MIC,
  83. ContentSettingsType::SENSORS,
  84. ContentSettingsType::NOTIFICATIONS,
  85. ContentSettingsType::JAVASCRIPT,
  86. #if !BUILDFLAG(IS_ANDROID)
  87. ContentSettingsType::IMAGES,
  88. #endif
  89. ContentSettingsType::POPUPS,
  90. ContentSettingsType::WINDOW_PLACEMENT,
  91. ContentSettingsType::ADS,
  92. ContentSettingsType::BACKGROUND_SYNC,
  93. ContentSettingsType::SOUND,
  94. ContentSettingsType::AUTOMATIC_DOWNLOADS,
  95. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
  96. ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER,
  97. #endif
  98. ContentSettingsType::MIDI_SYSEX,
  99. ContentSettingsType::CLIPBOARD_READ_WRITE,
  100. #if BUILDFLAG(IS_ANDROID)
  101. ContentSettingsType::NFC,
  102. #endif
  103. ContentSettingsType::USB_GUARD,
  104. #if !BUILDFLAG(IS_ANDROID)
  105. ContentSettingsType::HID_GUARD,
  106. ContentSettingsType::SERIAL_GUARD,
  107. ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
  108. ContentSettingsType::LOCAL_FONTS,
  109. #endif
  110. ContentSettingsType::BLUETOOTH_GUARD,
  111. ContentSettingsType::BLUETOOTH_SCANNING,
  112. ContentSettingsType::VR,
  113. ContentSettingsType::AR,
  114. ContentSettingsType::IDLE_DETECTION,
  115. ContentSettingsType::FEDERATED_IDENTITY_API,
  116. };
  117. // Determines whether to show permission |type| in the Page Info UI. Only
  118. // applies to permissions listed in |kPermissionType|.
  119. bool ShouldShowPermission(const PageInfo::PermissionInfo& info,
  120. const GURL& site_url,
  121. HostContentSettingsMap* content_settings,
  122. content::WebContents* web_contents,
  123. bool changed_since_last_page_load,
  124. bool is_subresource_filter_activated) {
  125. // Note |ContentSettingsType::ADS| will show up regardless of its default
  126. // value when it has been activated on the current origin.
  127. if (info.type == ContentSettingsType::ADS) {
  128. if (!base::FeatureList::IsEnabled(
  129. subresource_filter::kSafeBrowsingSubresourceFilter)) {
  130. return false;
  131. }
  132. return is_subresource_filter_activated;
  133. }
  134. if (info.type == ContentSettingsType::SOUND) {
  135. // The sound content setting should always show up when the tab has played
  136. // audio.
  137. if (web_contents && web_contents->WasEverAudible())
  138. return true;
  139. }
  140. const bool is_incognito = web_contents->GetBrowserContext()->IsOffTheRecord();
  141. #if BUILDFLAG(IS_ANDROID)
  142. // Special geolocation DSE settings apply only on Android, so make sure it
  143. // gets checked there regardless of default setting on Desktop.
  144. // DSE settings don't apply to incognito mode.
  145. if (info.type == ContentSettingsType::GEOLOCATION && !is_incognito)
  146. return true;
  147. // The File System write permission is desktop only at the moment.
  148. if (info.type == ContentSettingsType::FILE_SYSTEM_WRITE_GUARD)
  149. return false;
  150. #else
  151. // NFC is Android-only at the moment.
  152. if (info.type == ContentSettingsType::NFC)
  153. return false;
  154. // Display the File System Access write permission if the File System Access
  155. // API is currently being used.
  156. if (info.type == ContentSettingsType::FILE_SYSTEM_WRITE_GUARD &&
  157. web_contents->HasFileSystemAccessHandles()) {
  158. return true;
  159. }
  160. // Hide camera if camera PTZ is granted or blocked.
  161. if (info.type == ContentSettingsType::MEDIASTREAM_CAMERA) {
  162. const base::Value value = content_settings->GetWebsiteSetting(
  163. site_url, site_url, ContentSettingsType::CAMERA_PAN_TILT_ZOOM, nullptr);
  164. DCHECK(value.is_int());
  165. ContentSetting camera_ptz_setting =
  166. content_settings::ValueToContentSetting(value);
  167. if (camera_ptz_setting == CONTENT_SETTING_ALLOW ||
  168. camera_ptz_setting == CONTENT_SETTING_BLOCK) {
  169. return false;
  170. }
  171. }
  172. #endif
  173. // Show the content setting if it has been changed by the user since the last
  174. // page load.
  175. if (changed_since_last_page_load) {
  176. return true;
  177. }
  178. // Show the Bluetooth guard permission if the new permissions backend is
  179. // enabled.
  180. if (info.type == ContentSettingsType::BLUETOOTH_GUARD &&
  181. base::FeatureList::IsEnabled(
  182. features::kWebBluetoothNewPermissionsBackend) &&
  183. !PageInfo::IsPermissionFactoryDefault(info, is_incognito)) {
  184. return true;
  185. }
  186. // Show the content setting when it has a non-default value.
  187. if (!PageInfo::IsPermissionFactoryDefault(info, is_incognito))
  188. return true;
  189. return false;
  190. }
  191. // If the |visible_security_state| indicates that mixed content or certificate
  192. // errors were present, update |connection_status| and |connection_details|.
  193. void ReportAnyInsecureContent(
  194. const security_state::VisibleSecurityState& visible_security_state,
  195. PageInfo::SiteConnectionStatus* connection_status,
  196. std::u16string* connection_details) {
  197. bool displayed_insecure_content =
  198. visible_security_state.displayed_mixed_content;
  199. bool ran_insecure_content = visible_security_state.ran_mixed_content;
  200. // Only note subresources with certificate errors if the main resource was
  201. // loaded without major certificate errors. If the main resource had a
  202. // certificate error, then it would not be that useful (and could
  203. // potentially be confusing) to warn about subresources that had certificate
  204. // errors too.
  205. if (!net::IsCertStatusError(visible_security_state.cert_status)) {
  206. displayed_insecure_content =
  207. displayed_insecure_content ||
  208. visible_security_state.displayed_content_with_cert_errors;
  209. ran_insecure_content = ran_insecure_content ||
  210. visible_security_state.ran_content_with_cert_errors;
  211. }
  212. // Only one insecure content warning is displayed; show the most severe.
  213. if (ran_insecure_content) {
  214. *connection_status =
  215. PageInfo::SITE_CONNECTION_STATUS_INSECURE_ACTIVE_SUBRESOURCE;
  216. connection_details->assign(l10n_util::GetStringFUTF16(
  217. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, *connection_details,
  218. l10n_util::GetStringUTF16(
  219. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR)));
  220. return;
  221. }
  222. if (visible_security_state.contained_mixed_form) {
  223. *connection_status = PageInfo::SITE_CONNECTION_STATUS_INSECURE_FORM_ACTION;
  224. connection_details->assign(l10n_util::GetStringFUTF16(
  225. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, *connection_details,
  226. l10n_util::GetStringUTF16(
  227. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_FORM_WARNING)));
  228. return;
  229. }
  230. if (displayed_insecure_content) {
  231. *connection_status =
  232. PageInfo::SITE_CONNECTION_STATUS_INSECURE_PASSIVE_SUBRESOURCE;
  233. connection_details->assign(l10n_util::GetStringFUTF16(
  234. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, *connection_details,
  235. l10n_util::GetStringUTF16(
  236. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING)));
  237. }
  238. }
  239. // The list of chooser types that need to display entries in the Website
  240. // Settings UI. THE ORDER OF THESE ITEMS IS IMPORTANT. To propose changing it,
  241. // email security-dev@chromium.org.
  242. const PageInfo::ChooserUIInfo kChooserUIInfo[] = {
  243. {ContentSettingsType::USB_CHOOSER_DATA,
  244. IDS_PAGE_INFO_USB_DEVICE_SECONDARY_LABEL,
  245. IDS_PAGE_INFO_USB_DEVICE_ALLOWED_BY_POLICY_LABEL,
  246. IDS_PAGE_INFO_DELETE_USB_DEVICE},
  247. #if !BUILDFLAG(IS_ANDROID)
  248. {ContentSettingsType::HID_CHOOSER_DATA,
  249. IDS_PAGE_INFO_HID_DEVICE_SECONDARY_LABEL,
  250. IDS_PAGE_INFO_HID_DEVICE_ALLOWED_BY_POLICY_LABEL,
  251. IDS_PAGE_INFO_DELETE_HID_DEVICE},
  252. {ContentSettingsType::SERIAL_CHOOSER_DATA,
  253. IDS_PAGE_INFO_SERIAL_PORT_SECONDARY_LABEL,
  254. IDS_PAGE_INFO_SERIAL_PORT_ALLOWED_BY_POLICY_LABEL,
  255. IDS_PAGE_INFO_DELETE_SERIAL_PORT},
  256. #endif
  257. {ContentSettingsType::BLUETOOTH_CHOOSER_DATA,
  258. IDS_PAGE_INFO_BLUETOOTH_DEVICE_SECONDARY_LABEL,
  259. /*allowed_by_policy_description_string_id=*/-1,
  260. IDS_PAGE_INFO_DELETE_BLUETOOTH_DEVICE},
  261. };
  262. void LogTimeOpenHistogram(const std::string& name, base::TimeTicks start_time) {
  263. base::UmaHistogramCustomTimes(name, base::TimeTicks::Now() - start_time,
  264. base::Milliseconds(1), base::Hours(1), 100);
  265. }
  266. // Time open histogram prefixes.
  267. const char kPageInfoTimePrefix[] = "Security.PageInfo.TimeOpen";
  268. const char kPageInfoTimeActionPrefix[] = "Security.PageInfo.TimeOpen.Action";
  269. const char kPageInfoTimeNoActionPrefix[] =
  270. "Security.PageInfo.TimeOpen.NoAction";
  271. } // namespace
  272. PageInfo::PageInfo(std::unique_ptr<PageInfoDelegate> delegate,
  273. content::WebContents* web_contents,
  274. const GURL& url)
  275. : web_contents_(web_contents->GetWeakPtr()),
  276. delegate_(std::move(delegate)),
  277. show_info_bar_(false),
  278. site_url_(url),
  279. site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN),
  280. safe_browsing_status_(SAFE_BROWSING_STATUS_NONE),
  281. safety_tip_info_({security_state::SafetyTipStatus::kUnknown, GURL()}),
  282. site_connection_status_(SITE_CONNECTION_STATUS_UNKNOWN),
  283. show_ssl_decision_revoke_button_(false),
  284. did_revoke_user_ssl_decisions_(false),
  285. show_change_password_buttons_(false),
  286. did_perform_action_(false) {
  287. DCHECK(delegate_);
  288. security_level_ = delegate_->GetSecurityLevel();
  289. visible_security_state_for_metrics_ = delegate_->GetVisibleSecurityState();
  290. // TabSpecificContentSetting needs to be created before page load.
  291. DCHECK(GetPageSpecificContentSettings());
  292. ComputeUIInputs(site_url_);
  293. // Every time this is created, page info dialog is opened.
  294. // So this counts how often the page Info dialog is opened.
  295. RecordPageInfoAction(PAGE_INFO_OPENED);
  296. // Record the time when the page info dialog is opened so the total time it is
  297. // open can be measured.
  298. start_time_ = base::TimeTicks::Now();
  299. }
  300. PageInfo::~PageInfo() {
  301. // Check if Re-enable warnings button was visible, if so, log on UMA whether
  302. // it was clicked or not.
  303. SSLCertificateDecisionsDidRevoke user_decision =
  304. did_revoke_user_ssl_decisions_ ? USER_CERT_DECISIONS_REVOKED
  305. : USER_CERT_DECISIONS_NOT_REVOKED;
  306. if (show_ssl_decision_revoke_button_) {
  307. base::UmaHistogramEnumeration(
  308. "interstitial.ssl.did_user_revoke_decisions2", user_decision,
  309. END_OF_SSL_CERTIFICATE_DECISIONS_DID_REVOKE_ENUM);
  310. }
  311. // Record the total time the Page Info UI was open for all opens as well as
  312. // split between whether any action was taken.
  313. LogTimeOpenHistogram(security_state::GetSecurityLevelHistogramName(
  314. kPageInfoTimePrefix, security_level_),
  315. start_time_);
  316. LogTimeOpenHistogram(security_state::GetSafetyTipHistogramName(
  317. kPageInfoTimePrefix, safety_tip_info_.status),
  318. start_time_);
  319. if (did_perform_action_) {
  320. LogTimeOpenHistogram(security_state::GetSecurityLevelHistogramName(
  321. kPageInfoTimeActionPrefix, security_level_),
  322. start_time_);
  323. LogTimeOpenHistogram(
  324. security_state::GetSafetyTipHistogramName(kPageInfoTimeActionPrefix,
  325. safety_tip_info_.status),
  326. start_time_);
  327. } else {
  328. LogTimeOpenHistogram(security_state::GetSecurityLevelHistogramName(
  329. kPageInfoTimeNoActionPrefix, security_level_),
  330. start_time_);
  331. LogTimeOpenHistogram(
  332. security_state::GetSafetyTipHistogramName(kPageInfoTimeNoActionPrefix,
  333. safety_tip_info_.status),
  334. start_time_);
  335. }
  336. }
  337. // static
  338. bool PageInfo::IsPermissionFactoryDefault(const PermissionInfo& info,
  339. bool is_incognito) {
  340. const ContentSetting factory_default_setting =
  341. content_settings::ContentSettingsRegistry::GetInstance()
  342. ->Get(info.type)
  343. ->GetInitialDefaultSetting();
  344. // Settings that are granted in regular mode get reduced to ASK in incognito
  345. // mode. These settings should not be displayed either.
  346. const bool is_incognito_default =
  347. is_incognito && info.setting == CONTENT_SETTING_ASK &&
  348. factory_default_setting == CONTENT_SETTING_ASK;
  349. return info.source == content_settings::SETTING_SOURCE_USER &&
  350. factory_default_setting == info.default_setting &&
  351. (info.setting == CONTENT_SETTING_DEFAULT || is_incognito_default);
  352. }
  353. // static
  354. bool PageInfo::IsFileOrInternalPage(const GURL& url) {
  355. return url.SchemeIs(content::kChromeUIScheme) ||
  356. url.SchemeIs(content::kChromeDevToolsScheme) ||
  357. url.SchemeIs(content::kViewSourceScheme) ||
  358. url.SchemeIs(url::kFileScheme);
  359. }
  360. void PageInfo::InitializeUiState(PageInfoUI* ui, base::OnceClosure done) {
  361. ui_ = ui;
  362. DCHECK(ui_);
  363. PresentSitePermissions();
  364. PresentSiteIdentity();
  365. PresentPageFeatureInfo();
  366. PresentSiteData(std::move(done));
  367. PresentAdPersonalizationData();
  368. }
  369. void PageInfo::UpdateSecurityState() {
  370. ComputeUIInputs(site_url_);
  371. PresentSiteIdentity();
  372. }
  373. void PageInfo::RecordPageInfoAction(PageInfoAction action) {
  374. if (action != PAGE_INFO_OPENED)
  375. did_perform_action_ = true;
  376. #if !BUILDFLAG(IS_ANDROID)
  377. delegate_->OnPageInfoActionOccurred(action);
  378. #endif
  379. base::UmaHistogramEnumeration("WebsiteSettings.Action", action);
  380. if (web_contents_) {
  381. ukm::builders::PageInfoBubble(
  382. web_contents_->GetPrimaryMainFrame()->GetPageUkmSourceId())
  383. .SetActionTaken(action)
  384. .Record(ukm::UkmRecorder::Get());
  385. }
  386. base::UmaHistogramEnumeration(
  387. security_state::GetSafetyTipHistogramName(
  388. "Security.SafetyTips.PageInfo.Action", safety_tip_info_.status),
  389. action);
  390. auto* settings = GetPageSpecificContentSettings();
  391. if (!settings)
  392. return;
  393. bool has_topic = settings->HasAccessedTopics();
  394. bool has_fledge = settings->HasJoinedUserToInterestGroup();
  395. switch (action) {
  396. case PageInfoAction::PAGE_INFO_OPENED:
  397. base::RecordAction(base::UserMetricsAction("PageInfo.Opened"));
  398. base::UmaHistogramBoolean("Security.PageInfo.AdPersonalizationRowShown",
  399. has_fledge || has_topic);
  400. break;
  401. case PageInfoAction::PAGE_INFO_AD_PERSONALIZATION_PAGE_OPENED:
  402. if (has_fledge && has_topic) {
  403. base::RecordAction(base::UserMetricsAction(
  404. "PageInfo.AdPersonalization.OpenedWithFledgeAndTopics"));
  405. } else if (has_fledge) {
  406. base::RecordAction(base::UserMetricsAction(
  407. "PageInfo.AdPersonalization.OpenedWithFledge"));
  408. } else if (has_topic) {
  409. base::RecordAction(base::UserMetricsAction(
  410. "PageInfo.AdPersonalization.OpenedWithTopics"));
  411. }
  412. break;
  413. case PageInfoAction::PAGE_INFO_AD_PERSONALIZATION_SETTINGS_OPENED:
  414. base::RecordAction(base::UserMetricsAction(
  415. "PageInfo.AdPersonalization.ManageInterestClicked"));
  416. break;
  417. case PAGE_INFO_CERTIFICATE_DIALOG_OPENED:
  418. base::RecordAction(
  419. base::UserMetricsAction("PageInfo.Security.Certificate.Opened"));
  420. break;
  421. case PAGE_INFO_CONNECTION_HELP_OPENED:
  422. base::RecordAction(
  423. base::UserMetricsAction("PageInfo.Security.ConnectionHelp.Opened"));
  424. break;
  425. case PAGE_INFO_SECURITY_DETAILS_OPENED:
  426. base::RecordAction(base::UserMetricsAction("PageInfo.Security.Opened"));
  427. break;
  428. case PAGE_INFO_SITE_SETTINGS_OPENED:
  429. base::RecordAction(
  430. base::UserMetricsAction("PageInfo.SiteSettings.Opened"));
  431. break;
  432. case PAGE_INFO_COOKIES_DIALOG_OPENED:
  433. base::RecordAction(base::UserMetricsAction("PageInfo.Cookies.Opened"));
  434. break;
  435. case PAGE_INFO_COOKIES_ALLOWED_FOR_SITE:
  436. base::RecordAction(base::UserMetricsAction("PageInfo.Cookies.Allowed"));
  437. break;
  438. case PAGE_INFO_COOKIES_BLOCKED_FOR_SITE:
  439. base::RecordAction(base::UserMetricsAction("PageInfo.Cookies.Blocked"));
  440. break;
  441. case PAGE_INFO_COOKIES_CLEARED:
  442. base::RecordAction(base::UserMetricsAction("PageInfo.Cookies.Cleared"));
  443. break;
  444. case PAGE_INFO_PERMISSION_DIALOG_OPENED:
  445. base::RecordAction(base::UserMetricsAction("PageInfo.Permission.Opened"));
  446. break;
  447. case PAGE_INFO_CHANGED_PERMISSION:
  448. base::RecordAction(
  449. base::UserMetricsAction("PageInfo.Permission.Changed"));
  450. break;
  451. case PAGE_INFO_PERMISSIONS_CLEARED:
  452. base::RecordAction(
  453. base::UserMetricsAction("PageInfo.Permission.Cleared"));
  454. break;
  455. case PAGE_INFO_CHOOSER_OBJECT_DELETED:
  456. base::RecordAction(
  457. base::UserMetricsAction("PageInfo.Permission.ChooserObjectDeleted"));
  458. break;
  459. case PAGE_INFO_RESET_DECISIONS_CLICKED:
  460. base::RecordAction(
  461. base::UserMetricsAction("PageInfo.Permission.ResetDecisions"));
  462. break;
  463. case PAGE_INFO_FORGET_SITE_OPENED:
  464. base::RecordAction(base::UserMetricsAction("PageInfo.ForgetSite.Opened"));
  465. break;
  466. case PAGE_INFO_FORGET_SITE_CLEARED:
  467. base::RecordAction(
  468. base::UserMetricsAction("PageInfo.ForgetSite.Cleared"));
  469. break;
  470. case PAGE_INFO_HISTORY_OPENED:
  471. base::RecordAction(base::UserMetricsAction("PageInfo.History.Opened"));
  472. break;
  473. case PAGE_INFO_HISTORY_ENTRY_REMOVED:
  474. base::RecordAction(
  475. base::UserMetricsAction("PageInfo.History.EntryRemoved"));
  476. break;
  477. case PAGE_INFO_HISTORY_ENTRY_CLICKED:
  478. base::RecordAction(
  479. base::UserMetricsAction("PageInfo.History.EntryClicked"));
  480. break;
  481. case PAGE_INFO_PASSWORD_REUSE_ALLOWED:
  482. base::RecordAction(
  483. base::UserMetricsAction("PageInfo.PasswordReuseAllowed"));
  484. break;
  485. case PAGE_INFO_CHANGE_PASSWORD_PRESSED:
  486. base::RecordAction(
  487. base::UserMetricsAction("PageInfo.ChangePasswordPressed"));
  488. break;
  489. case PAGE_INFO_SAFETY_TIP_HELP_OPENED:
  490. base::RecordAction(
  491. base::UserMetricsAction("PageInfo.SafetyTip.HelpOpened"));
  492. break;
  493. case PAGE_INFO_STORE_INFO_CLICKED:
  494. base::RecordAction(base::UserMetricsAction("PageInfo.StoreInfo.Opened"));
  495. break;
  496. case PAGE_INFO_ABOUT_THIS_SITE_PAGE_OPENED:
  497. base::RecordAction(
  498. base::UserMetricsAction("PageInfo.AboutThisSite.Opened"));
  499. break;
  500. case PAGE_INFO_ABOUT_THIS_SITE_SOURCE_LINK_CLICKED:
  501. base::RecordAction(
  502. base::UserMetricsAction("PageInfo.AboutThisSite.SourceLinkClicked"));
  503. break;
  504. case PAGE_INFO_ABOUT_THIS_SITE_MORE_ABOUT_CLICKED:
  505. base::RecordAction(
  506. base::UserMetricsAction("PageInfo.AboutThisSite.MoreAboutClicked"));
  507. break;
  508. case PAGE_INFO_COOKIES_PAGE_OPENED:
  509. // TODO(crbug.com/1346305) Add recording action.
  510. break;
  511. case PAGE_INFO_COOKIES_SETTINGS_OPENED:
  512. // TODO(crbug.com/1346305) Add recording action.
  513. case PAGE_INFO_ALL_SITES_OPENED:
  514. // TODO(crbug.com/1346305) Add recording action.
  515. break;
  516. }
  517. }
  518. void PageInfo::UpdatePermissions() {
  519. // Refresh the UI to reflect the new setting.
  520. PresentSitePermissions();
  521. }
  522. void PageInfo::OnSitePermissionChanged(ContentSettingsType type,
  523. ContentSetting setting,
  524. bool is_one_time) {
  525. ContentSettingChangedViaPageInfo(type);
  526. // Count how often a permission for a specific content type is changed using
  527. // the Page Info UI.
  528. size_t num_values;
  529. int histogram_value = ContentSettingTypeToHistogramValue(type, &num_values);
  530. base::UmaHistogramExactLinear("WebsiteSettings.OriginInfo.PermissionChanged",
  531. histogram_value, num_values);
  532. if (setting == ContentSetting::CONTENT_SETTING_ALLOW) {
  533. base::UmaHistogramExactLinear(
  534. "WebsiteSettings.OriginInfo.PermissionChanged.Allowed", histogram_value,
  535. num_values);
  536. } else if (setting == ContentSetting::CONTENT_SETTING_BLOCK) {
  537. base::UmaHistogramExactLinear(
  538. "WebsiteSettings.OriginInfo.PermissionChanged.Blocked", histogram_value,
  539. num_values);
  540. }
  541. // This is technically redundant given the histogram above, but putting the
  542. // total count of permission changes in another histogram makes it easier to
  543. // compare it against other kinds of actions in Page Info.
  544. RecordPageInfoAction(PAGE_INFO_CHANGED_PERMISSION);
  545. HostContentSettingsMap* content_settings = GetContentSettings();
  546. if (type == ContentSettingsType::SOUND) {
  547. ContentSetting default_setting = content_settings->GetDefaultContentSetting(
  548. ContentSettingsType::SOUND, nullptr);
  549. bool mute = (setting == CONTENT_SETTING_BLOCK) ||
  550. (setting == CONTENT_SETTING_DEFAULT &&
  551. default_setting == CONTENT_SETTING_BLOCK);
  552. if (mute) {
  553. base::RecordAction(
  554. base::UserMetricsAction("SoundContentSetting.MuteBy.PageInfo"));
  555. } else {
  556. base::RecordAction(
  557. base::UserMetricsAction("SoundContentSetting.UnmuteBy.PageInfo"));
  558. }
  559. }
  560. DCHECK(web_contents_);
  561. permissions::PermissionUmaUtil::ScopedRevocationReporter
  562. scoped_revocation_reporter(web_contents_->GetBrowserContext(), site_url_,
  563. site_url_, type,
  564. permissions::PermissionSourceUI::OIB);
  565. // The permission may have been blocked due to being under embargo, so if it
  566. // was changed away from BLOCK, clear embargo status if it exists.
  567. if (setting != CONTENT_SETTING_BLOCK) {
  568. delegate_->GetPermissionDecisionAutoblocker()->RemoveEmbargoAndResetCounts(
  569. site_url_, type);
  570. }
  571. using Constraints = content_settings::ContentSettingConstraints;
  572. content_settings->SetNarrowestContentSetting(
  573. site_url_, site_url_, type, setting,
  574. is_one_time
  575. ? Constraints{base::Time(), content_settings::SessionModel::OneTime}
  576. : Constraints{});
  577. // When the sound setting is changed, no reload is necessary.
  578. if (type != ContentSettingsType::SOUND)
  579. show_info_bar_ = true;
  580. // Refresh the UI to reflect the new setting.
  581. PresentSitePermissions();
  582. }
  583. void PageInfo::OnSiteChosenObjectDeleted(const ChooserUIInfo& ui_info,
  584. const base::Value& object) {
  585. permissions::ObjectPermissionContextBase* context =
  586. delegate_->GetChooserContext(ui_info.content_settings_type);
  587. const auto origin = url::Origin::Create(site_url_);
  588. context->RevokeObjectPermission(origin, object);
  589. show_info_bar_ = true;
  590. // Refresh the UI to reflect the changed settings.
  591. PresentSitePermissions();
  592. RecordPageInfoAction(PAGE_INFO_CHOOSER_OBJECT_DELETED);
  593. }
  594. void PageInfo::OnUIClosing(bool* reload_prompt) {
  595. if (reload_prompt)
  596. *reload_prompt = false;
  597. #if BUILDFLAG(IS_ANDROID)
  598. NOTREACHED();
  599. #else
  600. if (show_info_bar_ && web_contents_ && !web_contents_->IsBeingDestroyed()) {
  601. if (delegate_->CreateInfoBarDelegate() && reload_prompt)
  602. *reload_prompt = true;
  603. }
  604. delegate_->OnUIClosing();
  605. #endif
  606. }
  607. void PageInfo::OnRevokeSSLErrorBypassButtonPressed() {
  608. auto* stateful_ssl_host_state_delegate =
  609. delegate_->GetStatefulSSLHostStateDelegate();
  610. DCHECK(stateful_ssl_host_state_delegate);
  611. stateful_ssl_host_state_delegate->RevokeUserAllowExceptionsHard(
  612. site_url().host());
  613. did_revoke_user_ssl_decisions_ = true;
  614. RecordPageInfoAction(PAGE_INFO_RESET_DECISIONS_CLICKED);
  615. }
  616. void PageInfo::OpenSiteSettingsView() {
  617. #if BUILDFLAG(IS_ANDROID)
  618. NOTREACHED();
  619. #else
  620. RecordPageInfoAction(PAGE_INFO_SITE_SETTINGS_OPENED);
  621. delegate_->ShowSiteSettings(site_url());
  622. #endif
  623. }
  624. void PageInfo::OpenCookiesSettingsView() {
  625. #if BUILDFLAG(IS_ANDROID)
  626. NOTREACHED();
  627. #else
  628. RecordPageInfoAction(PAGE_INFO_COOKIES_SETTINGS_OPENED);
  629. delegate_->ShowCookiesSettings();
  630. #endif
  631. }
  632. void PageInfo::OpenAllSitesView() {
  633. #if BUILDFLAG(IS_ANDROID)
  634. NOTREACHED();
  635. #else
  636. RecordPageInfoAction(PAGE_INFO_ALL_SITES_OPENED);
  637. delegate_->ShowAllSitesSettings();
  638. #endif
  639. }
  640. void PageInfo::OpenCookiesDialog() {
  641. #if BUILDFLAG(IS_ANDROID)
  642. NOTREACHED();
  643. #else
  644. if (!web_contents_ || web_contents_->IsBeingDestroyed())
  645. return;
  646. RecordPageInfoAction(PAGE_INFO_COOKIES_DIALOG_OPENED);
  647. delegate_->OpenCookiesDialog();
  648. #endif
  649. }
  650. void PageInfo::OpenCertificateDialog(net::X509Certificate* certificate) {
  651. #if BUILDFLAG(IS_ANDROID)
  652. NOTREACHED();
  653. #else
  654. if (!web_contents_ || web_contents_->IsBeingDestroyed())
  655. return;
  656. gfx::NativeWindow top_window = web_contents_->GetTopLevelNativeWindow();
  657. if (certificate && top_window) {
  658. RecordPageInfoAction(PAGE_INFO_CERTIFICATE_DIALOG_OPENED);
  659. delegate_->OpenCertificateDialog(certificate);
  660. }
  661. #endif
  662. }
  663. void PageInfo::OpenSafetyTipHelpCenterPage() {
  664. #if BUILDFLAG(IS_ANDROID)
  665. NOTREACHED();
  666. #else
  667. RecordPageInfoAction(PAGE_INFO_SAFETY_TIP_HELP_OPENED);
  668. delegate_->OpenSafetyTipHelpCenterPage();
  669. #endif
  670. }
  671. void PageInfo::OpenConnectionHelpCenterPage(const ui::Event& event) {
  672. #if BUILDFLAG(IS_ANDROID)
  673. NOTREACHED();
  674. #else
  675. RecordPageInfoAction(PAGE_INFO_CONNECTION_HELP_OPENED);
  676. delegate_->OpenConnectionHelpCenterPage(event);
  677. #endif
  678. }
  679. void PageInfo::OpenContentSettingsExceptions(
  680. ContentSettingsType content_settings_type) {
  681. #if BUILDFLAG(IS_ANDROID)
  682. NOTREACHED();
  683. #else
  684. RecordPageInfoAction(PAGE_INFO_CONNECTION_HELP_OPENED);
  685. delegate_->OpenContentSettingsExceptions(content_settings_type);
  686. #endif
  687. }
  688. void PageInfo::OnChangePasswordButtonPressed() {
  689. #if BUILDFLAG(FULL_SAFE_BROWSING)
  690. RecordPageInfoAction(PAGE_INFO_CHANGE_PASSWORD_PRESSED);
  691. delegate_->OnUserActionOnPasswordUi(
  692. safe_browsing::WarningAction::CHANGE_PASSWORD);
  693. #endif
  694. }
  695. void PageInfo::OnAllowlistPasswordReuseButtonPressed() {
  696. #if BUILDFLAG(FULL_SAFE_BROWSING)
  697. RecordPageInfoAction(PAGE_INFO_PASSWORD_REUSE_ALLOWED);
  698. delegate_->OnUserActionOnPasswordUi(
  699. safe_browsing::WarningAction::MARK_AS_LEGITIMATE);
  700. #endif
  701. }
  702. permissions::ObjectPermissionContextBase* PageInfo::GetChooserContextFromUIInfo(
  703. const ChooserUIInfo& ui_info) const {
  704. return delegate_->GetChooserContext(ui_info.content_settings_type);
  705. }
  706. std::u16string PageInfo::GetSimpleSiteName() const {
  707. if (!site_name_for_testing_.empty())
  708. return site_name_for_testing_;
  709. return url_formatter::FormatUrlForDisplayOmitSchemePathAndTrivialSubdomains(
  710. site_url_);
  711. }
  712. void PageInfo::ComputeUIInputs(const GURL& url) {
  713. auto security_level = delegate_->GetSecurityLevel();
  714. auto visible_security_state = delegate_->GetVisibleSecurityState();
  715. #if !BUILDFLAG(IS_ANDROID)
  716. // On desktop, internal URLs aren't handled by this class. Instead, a
  717. // custom and simpler bubble is shown.
  718. DCHECK(!url.SchemeIs(content::kChromeUIScheme) &&
  719. !url.SchemeIs(content::kChromeDevToolsScheme) &&
  720. !url.SchemeIs(content::kViewSourceScheme) &&
  721. !url.SchemeIs(content_settings::kExtensionScheme));
  722. #endif
  723. bool is_chrome_ui_native_scheme = false;
  724. #if BUILDFLAG(IS_ANDROID)
  725. is_chrome_ui_native_scheme = url.SchemeIs(browser_ui::kChromeUINativeScheme);
  726. #endif
  727. if (url.SchemeIs(url::kAboutScheme)) {
  728. // All about: URLs except about:blank are redirected.
  729. DCHECK_EQ(url::kAboutBlankURL, url.spec());
  730. site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT;
  731. #if BUILDFLAG(IS_ANDROID)
  732. identity_status_description_android_ =
  733. l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY);
  734. #endif
  735. site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED;
  736. site_connection_details_ = l10n_util::GetStringFUTF16(
  737. IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
  738. UTF8ToUTF16(url.spec()));
  739. return;
  740. }
  741. if (url.SchemeIs(content::kChromeUIScheme) || is_chrome_ui_native_scheme) {
  742. site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE;
  743. #if BUILDFLAG(IS_ANDROID)
  744. identity_status_description_android_ =
  745. l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE);
  746. #endif
  747. site_connection_status_ = SITE_CONNECTION_STATUS_INTERNAL_PAGE;
  748. return;
  749. }
  750. // Identity section.
  751. certificate_ = visible_security_state.certificate;
  752. if (certificate_ &&
  753. (!net::IsCertStatusError(visible_security_state.cert_status))) {
  754. // HTTPS with no or minor errors.
  755. if (security_level == security_state::SECURE_WITH_POLICY_INSTALLED_CERT) {
  756. #if BUILDFLAG(IS_CHROMEOS_ASH)
  757. site_identity_status_ = SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT;
  758. #else
  759. DCHECK(false) << "Policy certificates exist only on ChromeOS";
  760. #endif
  761. } else {
  762. // No major or minor errors.
  763. if (visible_security_state.cert_status & net::CERT_STATUS_IS_EV) {
  764. // EV HTTPS page.
  765. site_identity_status_ = SITE_IDENTITY_STATUS_EV_CERT;
  766. } else {
  767. // Non-EV OK HTTPS page.
  768. site_identity_status_ = SITE_IDENTITY_STATUS_CERT;
  769. std::u16string issuer_name(
  770. UTF8ToUTF16(certificate_->issuer().GetDisplayName()));
  771. if (issuer_name.empty()) {
  772. issuer_name.assign(l10n_util::GetStringUTF16(
  773. IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
  774. }
  775. #if BUILDFLAG(IS_ANDROID)
  776. // This string is shown on all non-error HTTPS sites on Android when
  777. // the user taps "Details" link on page info.
  778. identity_status_description_android_.assign(l10n_util::GetStringFUTF16(
  779. IDS_PAGE_INFO_SECURE_IDENTITY_VERIFIED,
  780. delegate_->GetClientApplicationName(), issuer_name));
  781. #endif
  782. }
  783. if (security_state::IsSHA1InChain(visible_security_state)) {
  784. site_identity_status_ =
  785. SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM;
  786. #if BUILDFLAG(IS_ANDROID)
  787. identity_status_description_android_ +=
  788. u"\n\n" +
  789. l10n_util::GetStringUTF16(
  790. IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM);
  791. #endif
  792. }
  793. }
  794. } else {
  795. // HTTP or HTTPS with errors (not warnings).
  796. if (!security_state::IsSchemeCryptographic(visible_security_state.url) ||
  797. !visible_security_state.certificate) {
  798. site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT;
  799. } else {
  800. site_identity_status_ = SITE_IDENTITY_STATUS_ERROR;
  801. }
  802. #if BUILDFLAG(IS_ANDROID)
  803. const std::u16string bullet = u"\n • ";
  804. std::vector<ssl_errors::ErrorInfo> errors;
  805. ssl_errors::ErrorInfo::GetErrorsForCertStatus(
  806. certificate_, visible_security_state.cert_status, url, &errors);
  807. identity_status_description_android_.assign(l10n_util::GetStringUTF16(
  808. IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY));
  809. for (const ssl_errors::ErrorInfo& error : errors) {
  810. identity_status_description_android_ += bullet;
  811. identity_status_description_android_ += error.short_description();
  812. }
  813. if (visible_security_state.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) {
  814. identity_status_description_android_ += u"\n\n";
  815. identity_status_description_android_ +=
  816. l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME);
  817. }
  818. #endif
  819. }
  820. if (visible_security_state.malicious_content_status !=
  821. security_state::MALICIOUS_CONTENT_STATUS_NONE) {
  822. // The site has been flagged by Safe Browsing. Takes precedence over TLS.
  823. GetSafeBrowsingStatusByMaliciousContentStatus(
  824. visible_security_state.malicious_content_status, &safe_browsing_status_,
  825. &safe_browsing_details_);
  826. #if BUILDFLAG(IS_ANDROID)
  827. identity_status_description_android_ = safe_browsing_details_;
  828. #endif
  829. #if BUILDFLAG(FULL_SAFE_BROWSING)
  830. bool old_show_change_pw_buttons = show_change_password_buttons_;
  831. #endif
  832. show_change_password_buttons_ =
  833. (visible_security_state.malicious_content_status ==
  834. security_state::
  835. MALICIOUS_CONTENT_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE ||
  836. visible_security_state.malicious_content_status ==
  837. security_state::
  838. MALICIOUS_CONTENT_STATUS_SIGNED_IN_NON_SYNC_PASSWORD_REUSE ||
  839. visible_security_state.malicious_content_status ==
  840. security_state::
  841. MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE ||
  842. visible_security_state.malicious_content_status ==
  843. security_state::MALICIOUS_CONTENT_STATUS_SAVED_PASSWORD_REUSE);
  844. #if BUILDFLAG(FULL_SAFE_BROWSING)
  845. // Only record password reuse when adding the button, not on updates.
  846. if (show_change_password_buttons_ && !old_show_change_pw_buttons) {
  847. RecordPasswordReuseEvent();
  848. }
  849. #endif
  850. }
  851. safety_tip_info_ = visible_security_state.safety_tip_info;
  852. #if BUILDFLAG(IS_ANDROID)
  853. // identity_status_description_android_ is only displayed on Android when
  854. // the user taps "Details" link on the page info. Reuse the description from
  855. // page info UI.
  856. std::unique_ptr<PageInfoUI::SecurityDescription> security_description =
  857. PageInfoUI::CreateSafetyTipSecurityDescription(safety_tip_info_);
  858. if (security_description) {
  859. identity_status_description_android_ = security_description->details;
  860. }
  861. #endif
  862. // Site Connection
  863. // We consider anything less than 80 bits encryption to be weak encryption.
  864. // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and
  865. // weakly encrypted connections.
  866. site_connection_status_ = SITE_CONNECTION_STATUS_UNKNOWN;
  867. std::u16string subject_name(GetSimpleSiteName());
  868. if (subject_name.empty()) {
  869. subject_name.assign(
  870. l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY));
  871. }
  872. if (!visible_security_state.certificate ||
  873. !security_state::IsSchemeCryptographic(visible_security_state.url)) {
  874. // Page is still loading (so SSL status is not yet available) or
  875. // loaded over HTTP or loaded over HTTPS with no cert.
  876. site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED;
  877. site_connection_details_.assign(l10n_util::GetStringFUTF16(
  878. IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
  879. subject_name));
  880. } else if (!visible_security_state.connection_info_initialized) {
  881. DCHECK_NE(security_level, security_state::NONE);
  882. site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED_ERROR;
  883. } else {
  884. site_connection_status_ = SITE_CONNECTION_STATUS_ENCRYPTED;
  885. if (net::ObsoleteSSLStatus(
  886. visible_security_state.connection_status,
  887. visible_security_state.peer_signature_algorithm) ==
  888. net::OBSOLETE_SSL_NONE) {
  889. site_connection_details_.assign(l10n_util::GetStringFUTF16(
  890. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, subject_name));
  891. } else {
  892. site_connection_details_.assign(l10n_util::GetStringFUTF16(
  893. IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT,
  894. subject_name));
  895. }
  896. ReportAnyInsecureContent(visible_security_state, &site_connection_status_,
  897. &site_connection_details_);
  898. }
  899. uint16_t cipher_suite = net::SSLConnectionStatusToCipherSuite(
  900. visible_security_state.connection_status);
  901. if (visible_security_state.connection_info_initialized && cipher_suite) {
  902. int ssl_version = net::SSLConnectionStatusToVersion(
  903. visible_security_state.connection_status);
  904. const char* ssl_version_str;
  905. net::SSLVersionToString(&ssl_version_str, ssl_version);
  906. site_connection_details_ += u"\n\n";
  907. site_connection_details_ += l10n_util::GetStringFUTF16(
  908. IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION, ASCIIToUTF16(ssl_version_str));
  909. const char *key_exchange, *cipher, *mac;
  910. bool is_aead, is_tls13;
  911. net::SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead,
  912. &is_tls13, cipher_suite);
  913. site_connection_details_ += u"\n\n";
  914. if (is_aead) {
  915. if (is_tls13) {
  916. // For TLS 1.3 ciphers, report the group (historically, curve) as the
  917. // key exchange.
  918. key_exchange =
  919. SSL_get_curve_name(visible_security_state.key_exchange_group);
  920. if (!key_exchange) {
  921. NOTREACHED();
  922. key_exchange = "";
  923. }
  924. }
  925. site_connection_details_ += l10n_util::GetStringFUTF16(
  926. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD,
  927. ASCIIToUTF16(cipher), ASCIIToUTF16(key_exchange));
  928. } else {
  929. site_connection_details_ += l10n_util::GetStringFUTF16(
  930. IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS, ASCIIToUTF16(cipher),
  931. ASCIIToUTF16(mac), ASCIIToUTF16(key_exchange));
  932. }
  933. }
  934. // Check if a user decision has been made to allow or deny certificates with
  935. // errors on this site.
  936. StatefulSSLHostStateDelegate* delegate =
  937. delegate_->GetStatefulSSLHostStateDelegate();
  938. DCHECK(delegate);
  939. // Only show an SSL decision revoke button if the user has chosen to bypass
  940. // SSL host errors for this host in the past, and we're not presently on a
  941. // Safe Browsing error (since otherwise it's confusing which warning you're
  942. // re-enabling).
  943. DCHECK(web_contents_);
  944. show_ssl_decision_revoke_button_ =
  945. delegate->HasAllowException(
  946. url.host(),
  947. web_contents_->GetPrimaryMainFrame()->GetStoragePartition()) &&
  948. visible_security_state.malicious_content_status ==
  949. security_state::MALICIOUS_CONTENT_STATUS_NONE;
  950. }
  951. void PageInfo::PresentSitePermissions() {
  952. PermissionInfoList permission_info_list;
  953. ChosenObjectInfoList chosen_object_info_list;
  954. PermissionInfo permission_info;
  955. HostContentSettingsMap* content_settings = GetContentSettings();
  956. DCHECK(web_contents_);
  957. for (const ContentSettingsType type : kPermissionType) {
  958. permission_info.type = type;
  959. content_settings::SettingInfo info;
  960. // TODO(crbug.com/1030245) Investigate why the value is queried from the low
  961. // level routine GetWebsiteSettings.
  962. const base::Value value = content_settings->GetWebsiteSetting(
  963. site_url_, site_url_, permission_info.type, &info);
  964. if (value.is_int()) {
  965. permission_info.setting = content_settings::ValueToContentSetting(value);
  966. } else {
  967. NOTREACHED();
  968. }
  969. permission_info.source = info.source;
  970. permission_info.is_one_time =
  971. (info.session_model == content_settings::SessionModel::OneTime);
  972. if (info.primary_pattern == ContentSettingsPattern::Wildcard() &&
  973. info.secondary_pattern == ContentSettingsPattern::Wildcard()) {
  974. permission_info.default_setting = permission_info.setting;
  975. permission_info.setting = CONTENT_SETTING_DEFAULT;
  976. } else {
  977. permission_info.default_setting =
  978. content_settings->GetDefaultContentSetting(permission_info.type,
  979. nullptr);
  980. }
  981. // Check embargo status if the content setting supports embargo.
  982. if (permissions::PermissionDecisionAutoBlocker::IsEnabledForContentSetting(
  983. permission_info.type) &&
  984. permission_info.setting == CONTENT_SETTING_DEFAULT &&
  985. permission_info.source ==
  986. content_settings::SettingSource::SETTING_SOURCE_USER) {
  987. permissions::PermissionResult permission_result(
  988. CONTENT_SETTING_DEFAULT,
  989. permissions::PermissionStatusSource::UNSPECIFIED);
  990. if (permissions::PermissionUtil::IsPermission(permission_info.type)) {
  991. permission_result = delegate_->GetPermissionResult(
  992. permissions::PermissionUtil::ContentSettingTypeToPermissionType(
  993. permission_info.type),
  994. url::Origin::Create(site_url_));
  995. } else if (permission_info.type ==
  996. ContentSettingsType::FEDERATED_IDENTITY_API) {
  997. absl::optional<permissions::PermissionResult> embargo_result =
  998. delegate_->GetPermissionDecisionAutoblocker()->GetEmbargoResult(
  999. site_url_, permission_info.type);
  1000. if (embargo_result)
  1001. permission_result = *embargo_result;
  1002. }
  1003. // If under embargo, update |permission_info| to reflect that.
  1004. if (permission_result.content_setting == CONTENT_SETTING_BLOCK &&
  1005. (permission_result.source ==
  1006. permissions::PermissionStatusSource::MULTIPLE_DISMISSALS ||
  1007. permission_result.source ==
  1008. permissions::PermissionStatusSource::MULTIPLE_IGNORES)) {
  1009. permission_info.setting = permission_result.content_setting;
  1010. }
  1011. }
  1012. if (ShouldShowPermission(
  1013. permission_info, site_url_, content_settings, web_contents_.get(),
  1014. HasContentSettingChangedViaPageInfo(permission_info.type),
  1015. delegate_->IsSubresourceFilterActivated(site_url_))) {
  1016. permission_info_list.push_back(permission_info);
  1017. }
  1018. }
  1019. const auto origin = url::Origin::Create(site_url_);
  1020. for (const ChooserUIInfo& ui_info : kChooserUIInfo) {
  1021. permissions::ObjectPermissionContextBase* context =
  1022. delegate_->GetChooserContext(ui_info.content_settings_type);
  1023. if (!context)
  1024. continue;
  1025. auto chosen_objects = context->GetGrantedObjects(origin);
  1026. for (std::unique_ptr<permissions::ObjectPermissionContextBase::Object>&
  1027. object : chosen_objects) {
  1028. chosen_object_info_list.push_back(
  1029. std::make_unique<PageInfoUI::ChosenObjectInfo>(ui_info,
  1030. std::move(object)));
  1031. }
  1032. }
  1033. ui_->SetPermissionInfo(permission_info_list,
  1034. std::move(chosen_object_info_list));
  1035. }
  1036. void PageInfo::PresentSiteDataInternal(base::OnceClosure done) {
  1037. // Since this is called asynchronously, the associated `WebContents` object
  1038. // might no longer be available.
  1039. if (!web_contents_ || web_contents_->IsBeingDestroyed())
  1040. return;
  1041. bool is_cookies_subpage_enabled = false;
  1042. #if !BUILDFLAG(IS_ANDROID)
  1043. is_cookies_subpage_enabled =
  1044. base::FeatureList::IsEnabled(page_info::kPageInfoCookiesSubpage);
  1045. #endif
  1046. if (is_cookies_subpage_enabled) {
  1047. // Add allowed sites count.
  1048. PageInfoUI::CookiesNewInfo cookies_info;
  1049. cookies_info.allowed_sites_count = GetSitesWithAllowedCookiesAccessCount();
  1050. cookies_info.blocked_sites_count =
  1051. GetThirdPartySitesWithBlockedCookiesAccessCount(site_url_);
  1052. // TODO(crbug.com/1346305): Add dummy function for FPS information.
  1053. if (privacy_sandbox::kPrivacySandboxFirstPartySetsUISampleSets.Get() &&
  1054. site_url_.host() == "example.com") {
  1055. cookies_info.fps_info.owner_name = u"example.com";
  1056. }
  1057. ui_->SetCookieInfo(cookies_info);
  1058. } else {
  1059. CookieInfoList cookie_info_list;
  1060. // Add first party cookie and site data counts.
  1061. PageInfoUI::CookieInfo cookie_info;
  1062. cookie_info.allowed = GetFirstPartyAllowedCookiesCount(site_url_);
  1063. cookie_info.blocked = GetFirstPartyBlockedCookiesCount(site_url_);
  1064. cookie_info.is_first_party = true;
  1065. cookie_info_list.push_back(cookie_info);
  1066. // Add third party cookie counts.
  1067. cookie_info.allowed = GetThirdPartyAllowedCookiesCount(site_url_);
  1068. cookie_info.blocked = GetThirdPartyBlockedCookiesCount(site_url_);
  1069. cookie_info.is_first_party = false;
  1070. cookie_info_list.push_back(cookie_info);
  1071. ui_->SetCookieInfo(cookie_info_list);
  1072. }
  1073. std::move(done).Run();
  1074. }
  1075. void PageInfo::PresentSiteData(base::OnceClosure done) {
  1076. auto* settings = GetPageSpecificContentSettings();
  1077. if (settings) {
  1078. settings->allowed_local_shared_objects().UpdateIgnoredEmptyStorageKeys(
  1079. base::BindOnce(&PageInfo::PresentSiteDataInternal,
  1080. weak_factory_.GetWeakPtr(), std::move(done)));
  1081. }
  1082. }
  1083. void PageInfo::PresentSiteIdentity() {
  1084. // After initialization the status about the site's connection and its
  1085. // identity must be available.
  1086. DCHECK_NE(site_identity_status_, SITE_IDENTITY_STATUS_UNKNOWN);
  1087. DCHECK_NE(site_connection_status_, SITE_CONNECTION_STATUS_UNKNOWN);
  1088. PageInfoUI::IdentityInfo info;
  1089. info.site_identity = UTF16ToUTF8(GetSimpleSiteName());
  1090. info.connection_status = site_connection_status_;
  1091. info.connection_status_description = UTF16ToUTF8(site_connection_details_);
  1092. info.identity_status = site_identity_status_;
  1093. info.safe_browsing_status = safe_browsing_status_;
  1094. info.safe_browsing_details = safe_browsing_details_;
  1095. info.safety_tip_info = safety_tip_info_;
  1096. #if BUILDFLAG(IS_ANDROID)
  1097. info.identity_status_description_android =
  1098. UTF16ToUTF8(identity_status_description_android_);
  1099. #endif
  1100. info.certificate = certificate_;
  1101. info.show_ssl_decision_revoke_button = show_ssl_decision_revoke_button_;
  1102. info.show_change_password_buttons = show_change_password_buttons_;
  1103. ui_->SetIdentityInfo(info);
  1104. }
  1105. void PageInfo::PresentPageFeatureInfo() {
  1106. PageInfoUI::PageFeatureInfo info;
  1107. info.is_vr_presentation_in_headset =
  1108. delegate_->IsContentDisplayedInVrHeadset();
  1109. ui_->SetPageFeatureInfo(info);
  1110. }
  1111. void PageInfo::PresentAdPersonalizationData() {
  1112. PageInfoUI::AdPersonalizationInfo info;
  1113. auto* settings = GetPageSpecificContentSettings();
  1114. if (!settings)
  1115. return;
  1116. info.has_joined_user_to_interest_group =
  1117. settings->HasJoinedUserToInterestGroup();
  1118. info.accessed_topics = settings->GetAccessedTopics();
  1119. std::sort(info.accessed_topics.begin(), info.accessed_topics.end(),
  1120. [](const privacy_sandbox::CanonicalTopic& a,
  1121. const privacy_sandbox::CanonicalTopic& b) {
  1122. return a.GetLocalizedRepresentation() <
  1123. b.GetLocalizedRepresentation();
  1124. });
  1125. ui_->SetAdPersonalizationInfo(info);
  1126. }
  1127. #if BUILDFLAG(FULL_SAFE_BROWSING)
  1128. void PageInfo::RecordPasswordReuseEvent() {
  1129. auto* password_protection_service = delegate_->GetPasswordProtectionService();
  1130. if (!password_protection_service) {
  1131. return;
  1132. }
  1133. safe_browsing::LogWarningAction(
  1134. safe_browsing::WarningUIType::PAGE_INFO,
  1135. safe_browsing::WarningAction::SHOWN,
  1136. password_protection_service
  1137. ->reused_password_account_type_for_last_shown_warning());
  1138. }
  1139. #endif
  1140. HostContentSettingsMap* PageInfo::GetContentSettings() const {
  1141. return delegate_->GetContentSettings();
  1142. }
  1143. std::vector<ContentSettingsType> PageInfo::GetAllPermissionsForTesting() {
  1144. std::vector<ContentSettingsType> permission_list;
  1145. for (const ContentSettingsType type : kPermissionType)
  1146. permission_list.push_back(type);
  1147. return permission_list;
  1148. }
  1149. void PageInfo::SetSiteNameForTesting(const std::u16string& site_name) {
  1150. site_name_for_testing_ = site_name;
  1151. PresentSiteIdentity();
  1152. }
  1153. void PageInfo::GetSafeBrowsingStatusByMaliciousContentStatus(
  1154. security_state::MaliciousContentStatus malicious_content_status,
  1155. PageInfo::SafeBrowsingStatus* status,
  1156. std::u16string* details) {
  1157. switch (malicious_content_status) {
  1158. case security_state::MALICIOUS_CONTENT_STATUS_NONE:
  1159. NOTREACHED();
  1160. break;
  1161. case security_state::MALICIOUS_CONTENT_STATUS_MALWARE:
  1162. *status = PageInfo::SAFE_BROWSING_STATUS_MALWARE;
  1163. *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_DETAILS);
  1164. break;
  1165. case security_state::MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING:
  1166. *status = PageInfo::SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING;
  1167. *details =
  1168. l10n_util::GetStringUTF16(IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS);
  1169. break;
  1170. case security_state::MALICIOUS_CONTENT_STATUS_UNWANTED_SOFTWARE:
  1171. *status = PageInfo::SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE;
  1172. *details =
  1173. l10n_util::GetStringUTF16(IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS);
  1174. break;
  1175. case security_state::MALICIOUS_CONTENT_STATUS_SAVED_PASSWORD_REUSE:
  1176. #if BUILDFLAG(FULL_SAFE_BROWSING)
  1177. *status = PageInfo::SAFE_BROWSING_STATUS_SAVED_PASSWORD_REUSE;
  1178. *details = delegate_->GetWarningDetailText();
  1179. #endif
  1180. break;
  1181. case security_state::MALICIOUS_CONTENT_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE:
  1182. #if BUILDFLAG(FULL_SAFE_BROWSING)
  1183. *status = PageInfo::SAFE_BROWSING_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE;
  1184. *details = delegate_->GetWarningDetailText();
  1185. #endif
  1186. break;
  1187. case security_state::
  1188. MALICIOUS_CONTENT_STATUS_SIGNED_IN_NON_SYNC_PASSWORD_REUSE:
  1189. #if BUILDFLAG(FULL_SAFE_BROWSING)
  1190. *status =
  1191. PageInfo::SAFE_BROWSING_STATUS_SIGNED_IN_NON_SYNC_PASSWORD_REUSE;
  1192. *details = delegate_->GetWarningDetailText();
  1193. #endif
  1194. break;
  1195. case security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE:
  1196. #if BUILDFLAG(FULL_SAFE_BROWSING)
  1197. *status = PageInfo::SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE;
  1198. *details = delegate_->GetWarningDetailText();
  1199. #endif
  1200. break;
  1201. case security_state::MALICIOUS_CONTENT_STATUS_BILLING:
  1202. *status = PageInfo::SAFE_BROWSING_STATUS_BILLING;
  1203. *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_BILLING_DETAILS);
  1204. break;
  1205. }
  1206. }
  1207. content_settings::PageSpecificContentSettings*
  1208. PageInfo::GetPageSpecificContentSettings() const {
  1209. // TODO(https://crbug.com/1103176, https://crbug.com/1233122): PageInfo should
  1210. // be per page. Why is it a WebContentsObserver if it is not observing
  1211. // anything?
  1212. DCHECK(web_contents_);
  1213. return content_settings::PageSpecificContentSettings::GetForFrame(
  1214. web_contents_->GetPrimaryMainFrame());
  1215. }
  1216. bool PageInfo::HasContentSettingChangedViaPageInfo(ContentSettingsType type) {
  1217. auto* settings = GetPageSpecificContentSettings();
  1218. if (!settings)
  1219. return false;
  1220. return settings->HasContentSettingChangedViaPageInfo(type);
  1221. }
  1222. void PageInfo::ContentSettingChangedViaPageInfo(ContentSettingsType type) {
  1223. auto* settings = GetPageSpecificContentSettings();
  1224. if (!settings)
  1225. return;
  1226. return settings->ContentSettingChangedViaPageInfo(type);
  1227. }
  1228. int PageInfo::GetFirstPartyAllowedCookiesCount(const GURL& site_url) {
  1229. auto* settings = GetPageSpecificContentSettings();
  1230. if (!settings)
  1231. return 0;
  1232. return settings->allowed_local_shared_objects().GetObjectCountForDomain(
  1233. site_url);
  1234. }
  1235. int PageInfo::GetSitesWithAllowedCookiesAccessCount() {
  1236. auto* settings = GetPageSpecificContentSettings();
  1237. if (!settings)
  1238. return 0;
  1239. return settings->allowed_local_shared_objects().GetHostCount();
  1240. }
  1241. int PageInfo::GetThirdPartySitesWithBlockedCookiesAccessCount(
  1242. const GURL& site_url) {
  1243. auto* settings = GetPageSpecificContentSettings();
  1244. if (!settings)
  1245. return 0;
  1246. return settings->blocked_local_shared_objects().GetHostCount() -
  1247. settings->blocked_local_shared_objects().GetHostCountForDomain(
  1248. site_url);
  1249. }
  1250. int PageInfo::GetFirstPartyBlockedCookiesCount(const GURL& site_url) {
  1251. auto* settings = GetPageSpecificContentSettings();
  1252. if (!settings)
  1253. return 0;
  1254. return settings->blocked_local_shared_objects().GetObjectCountForDomain(
  1255. site_url);
  1256. }
  1257. int PageInfo::GetThirdPartyAllowedCookiesCount(const GURL& site_url) {
  1258. auto* settings = GetPageSpecificContentSettings();
  1259. if (!settings)
  1260. return 0;
  1261. return settings->allowed_local_shared_objects().GetObjectCount() -
  1262. GetFirstPartyAllowedCookiesCount(site_url);
  1263. }
  1264. int PageInfo::GetThirdPartyBlockedCookiesCount(const GURL& site_url) {
  1265. auto* settings = GetPageSpecificContentSettings();
  1266. if (!settings)
  1267. return 0;
  1268. return settings->blocked_local_shared_objects().GetObjectCount() -
  1269. GetFirstPartyBlockedCookiesCount(site_url);
  1270. }