mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1729640 - P4. Setting high-value permission for sites that are considered is logged in. r=farre,sfoster,tgiles
Sites that match the following heuristic are considered high-value: 1. Sites that have a password stored in the password manager 2. Sites that we detect that users submit a form with a password This patch adds LoginDetectionService to detect login attempts. When LoginDetectionService finds a site that matches any of the above heuristics, it adds the corresponding high-value permission to the permission manager. Differential Revision: https://phabricator.services.mozilla.com/D127105
This commit is contained in:
parent
1170d5bd99
commit
4744525d0d
@ -2673,6 +2673,16 @@ BrowserGlue.prototype = {
|
||||
},
|
||||
},
|
||||
|
||||
// Login detection service is used in fission to identify high value sites.
|
||||
{
|
||||
task: () => {
|
||||
let loginDetection = Cc[
|
||||
"@mozilla.org/login-detection-service;1"
|
||||
].createInstance(Ci.nsILoginDetectionService);
|
||||
loginDetection.init();
|
||||
},
|
||||
},
|
||||
|
||||
// WebDriver components (Remote Agent and Marionette) need to be
|
||||
// initialized as very last step.
|
||||
{
|
||||
|
137
dom/ipc/LoginDetectionService.cpp
Normal file
137
dom/ipc/LoginDetectionService.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "LoginDetectionService.h"
|
||||
|
||||
#include "nsILoginInfo.h"
|
||||
#include "nsILoginManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticPrefs_fission.h"
|
||||
#include "mozilla/dom/ProcessIsolation.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
static StaticRefPtr<LoginDetectionService> gLoginDetectionService;
|
||||
|
||||
namespace {
|
||||
|
||||
void OnFissionPrefsChange(const char* aPrefName, void* aData) {
|
||||
MOZ_ASSERT(gLoginDetectionService);
|
||||
|
||||
gLoginDetectionService->MaybeStartMonitoring();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS(LoginDetectionService, nsILoginDetectionService,
|
||||
nsILoginSearchCallback, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
// static
|
||||
already_AddRefed<LoginDetectionService> LoginDetectionService::GetSingleton() {
|
||||
if (gLoginDetectionService) {
|
||||
return do_AddRef(gLoginDetectionService);
|
||||
}
|
||||
|
||||
gLoginDetectionService = new LoginDetectionService();
|
||||
ClearOnShutdown(&gLoginDetectionService);
|
||||
|
||||
return do_AddRef(gLoginDetectionService);
|
||||
}
|
||||
|
||||
LoginDetectionService::~LoginDetectionService() { UnregisterObserver(); }
|
||||
|
||||
void LoginDetectionService::MaybeStartMonitoring() {
|
||||
if (IsIsolateHighValueSiteEnabled()) {
|
||||
// We want to isolate sites with a saved password, so fetch saved logins
|
||||
// from the password manager, and then add the 'HighValue' permission.
|
||||
|
||||
// Note that we don't monitor whether a login is added or removed after
|
||||
// logins are fetched. For adding logins, this will be covered by form
|
||||
// submission detection heuristic. As for removing logins, it doesn't
|
||||
// provide security benefit just to NOT isolate the removed site. The site
|
||||
// will not be isolated when its permission expired.
|
||||
FetchLogins();
|
||||
|
||||
if (!mObs) {
|
||||
mObs = mozilla::services::GetObserverService();
|
||||
mObs->AddObserver(this, "passwordmgr-form-submission-detected", false);
|
||||
}
|
||||
} else {
|
||||
UnregisterObserver();
|
||||
}
|
||||
}
|
||||
|
||||
void LoginDetectionService::FetchLogins() {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsILoginManager> loginManager =
|
||||
do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(!loginManager)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << loginManager->GetAllLoginsWithCallbackAsync(this);
|
||||
}
|
||||
|
||||
void LoginDetectionService::UnregisterObserver() {
|
||||
if (mObs) {
|
||||
mObs->RemoveObserver(this, "passwordmgr-form-submission-detected");
|
||||
mObs = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsILoginDetectionService implementation
|
||||
NS_IMETHODIMP LoginDetectionService::Init() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Preferences::RegisterCallback(OnFissionPrefsChange, "fission.autostart");
|
||||
Preferences::RegisterCallback(OnFissionPrefsChange,
|
||||
"fission.webContentIsolationStrategy");
|
||||
|
||||
MaybeStartMonitoring();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsILoginSearchObserver implementation
|
||||
NS_IMETHODIMP
|
||||
LoginDetectionService::OnSearchComplete(
|
||||
const nsTArray<RefPtr<nsILoginInfo>>& aLogins) {
|
||||
// Add all origins with saved passwords to the permission manager.
|
||||
for (const auto& login : aLogins) {
|
||||
nsString origin;
|
||||
login->GetOrigin(origin);
|
||||
|
||||
AddHighValuePermission(NS_ConvertUTF16toUTF8(origin),
|
||||
mozilla::dom::kHighValueHasSavedLoginPermission);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIObserver implementation
|
||||
NS_IMETHODIMP
|
||||
LoginDetectionService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if ("passwordmgr-form-submission-detected"_ns.Equals(aTopic)) {
|
||||
nsDependentString origin(aData);
|
||||
AddHighValuePermission(NS_ConvertUTF16toUTF8(origin),
|
||||
mozilla::dom::kHighValueIsLoggedInPermission);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
57
dom/ipc/LoginDetectionService.h
Normal file
57
dom/ipc/LoginDetectionService.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_LoginDetectionService_h
|
||||
#define mozilla_dom_LoginDetectionService_h
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsILoginDetectionService.h"
|
||||
#include "nsILoginManager.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
/**
|
||||
* Detect whether the user is 'possibly' logged in to a site, and add the
|
||||
* HighValue permission to the permission manager. We say 'possibly' because
|
||||
* the detection is done in a very loose way. For example, for sites that have
|
||||
* an associated login stored in the password manager are considered `logged in`
|
||||
* by the service, which is not always true in terms of whether the users is
|
||||
* really logged in to the site.
|
||||
*/
|
||||
class LoginDetectionService final : public nsILoginDetectionService,
|
||||
public nsILoginSearchCallback,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSILOGINDETECTIONSERVICE
|
||||
NS_DECL_NSILOGINSEARCHCALLBACK
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static already_AddRefed<LoginDetectionService> GetSingleton();
|
||||
|
||||
void MaybeStartMonitoring();
|
||||
|
||||
private:
|
||||
LoginDetectionService() = default;
|
||||
virtual ~LoginDetectionService();
|
||||
|
||||
// Fetch saved logins from the password manager.
|
||||
void FetchLogins();
|
||||
|
||||
void RegisterObserver();
|
||||
void UnregisterObserver();
|
||||
|
||||
nsCOMPtr<nsIObserverService> mObs;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif
|
@ -955,4 +955,24 @@ void AddHighValuePermission(nsIPrincipal* aResultPrincipal,
|
||||
nsIPermissionManager::EXPIRE_TIME, expirationTime);
|
||||
}
|
||||
|
||||
void AddHighValuePermission(const nsACString& aOrigin,
|
||||
const nsACString& aPermissionType) {
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv =
|
||||
ssm->CreateContentPrincipalFromOrigin(aOrigin, getter_AddRefs(principal));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddHighValuePermission(principal, aPermissionType);
|
||||
}
|
||||
|
||||
bool IsIsolateHighValueSiteEnabled() {
|
||||
return mozilla::FissionAutostart() &&
|
||||
WebContentIsolationStrategy(
|
||||
StaticPrefs::fission_webContentIsolationStrategy()) ==
|
||||
WebContentIsolationStrategy::IsolateHighValue;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -13,9 +13,8 @@
|
||||
#include "mozilla/dom/RemoteType.h"
|
||||
#include "mozilla/dom/SessionHistoryEntry.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIPrincipal;
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
@ -80,6 +79,15 @@ Result<NavigationIsolationOptions, nsresult> IsolationOptionsForNavigation(
|
||||
void AddHighValuePermission(nsIPrincipal* aResultPrincipal,
|
||||
const nsACString& aPermissionType);
|
||||
|
||||
void AddHighValuePermission(const nsACString& aOrigin,
|
||||
const nsACString& aPermissionType);
|
||||
|
||||
/**
|
||||
* Returns true when fission is enabled and the
|
||||
* `fission.webContentIsolationStrategy` pref is set to `IsolateHighValue`.
|
||||
*/
|
||||
bool IsIsolateHighValueSiteEnabled();
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif
|
||||
|
16
dom/ipc/components.conf
Normal file
16
dom/ipc/components.conf
Normal file
@ -0,0 +1,16 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Classes = [
|
||||
{
|
||||
'cid': '{91fdaa4e-eba4-4ed3-831c-ce05c142822d}',
|
||||
'contract_ids': ['@mozilla.org/login-detection-service;1'],
|
||||
'type': 'mozilla::dom::LoginDetectionService',
|
||||
'singleton': True,
|
||||
'headers': ['/dom/ipc/LoginDetectionService.h'],
|
||||
'constructor': 'mozilla::dom::LoginDetectionService::GetSingleton',
|
||||
},
|
||||
]
|
@ -13,10 +13,15 @@ XPIDL_SOURCES += [
|
||||
"nsIDOMProcessChild.idl",
|
||||
"nsIDOMProcessParent.idl",
|
||||
"nsIHangReport.idl",
|
||||
"nsILoginDetectionService.idl",
|
||||
]
|
||||
|
||||
XPIDL_MODULE = "dom"
|
||||
|
||||
XPCOM_MANIFESTS += [
|
||||
"components.conf",
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"ManifestMessagesChild.jsm",
|
||||
]
|
||||
@ -53,6 +58,7 @@ EXPORTS.mozilla.dom += [
|
||||
"FilePickerParent.h",
|
||||
"InProcessChild.h",
|
||||
"InProcessParent.h",
|
||||
"LoginDetectionService.h",
|
||||
"MaybeDiscarded.h",
|
||||
"MemoryReportRequest.h",
|
||||
"NativeThreadId.h",
|
||||
@ -106,6 +112,7 @@ UNIFIED_SOURCES += [
|
||||
"DocShellMessageUtils.cpp",
|
||||
"FilePickerParent.cpp",
|
||||
"InProcessImpl.cpp",
|
||||
"LoginDetectionService.cpp",
|
||||
"MemMapSnapshot.cpp",
|
||||
"MemoryReportRequest.cpp",
|
||||
"MMPrinter.cpp",
|
||||
|
16
dom/ipc/nsILoginDetectionService.idl
Normal file
16
dom/ipc/nsILoginDetectionService.idl
Normal file
@ -0,0 +1,16 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
[scriptable, uuid(4c3c9a82-722a-4b0b-9c7d-36ef90135537)]
|
||||
interface nsILoginDetectionService : nsISupports
|
||||
{
|
||||
/**
|
||||
* called to initialize the login detection service.
|
||||
*/
|
||||
void init();
|
||||
};
|
Loading…
Reference in New Issue
Block a user