Google Cloud Fraud Defense lets you detect and prevent account takeovers (ATOs) across your websites and mobile applications. To help protect accounts against credential stuffing and automated takeovers, you can combine account-level behavioral analysis in Account defense with compromised-credential checks in Password defense and step-up multi-factor authentication (MFA).
ATO attacks, such as credential stuffing, typically occur when an attacker sends requests to sign in by using credentials exposed in data breaches and password dumps. Because users frequently reuse passwords across unrelated sites, automated stuffing attacks can succeed even against properly configured authentication endpoints unless you evaluate behavioral risk and leaked credentials.
Before you begin
Prepare your environment for Google Cloud Fraud Defense.
Detect and prevent ATOs
With Fraud Defense, you can detect and prevent ATOs by using the following capabilities:
- Account defense and the ATO risk score
- Password defense for password leak detection
- Score-based keys and step-up MFA
Use Account defense and the ATO risk score
Account defense is the primary capability for detecting and preventing ATOs across websites and mobile apps.
Account defense provides a dedicated
ATO risk score
(accountDefenderAssessment.accountTakeoverVerdict.risk, ranging from 0.0 to
1.0) and explainability signals (riskReasons and trustReasons). These
signals evaluate account-level behavioral history alongside session signals,
providing approximately four times higher ATO detection precision than bot
scores alone.
To integrate Account defense, pass a stable account identifier in the
user_info.account_id field (event.userInfo.accountId when you call
CreateAssessment.
If the account identifier is available only after authentication, pass
account_id when you call
AnnotateAssessment.
Detect leaked passwords
Because ATOs frequently rely on credential stuffing with credentials exposed in password dumps, use Password defense on sign-in, password-change, and password-reset flows to detect compromised credentials.
When you check credentials during an assessment, Password defense evaluates
the canonicalized username and password hash prefix against known data breaches
without exposing plaintext credentials to Google. When you call
CreateAssessment,
pass the username (credentials.username) hash prefix (lookupHashPrefix) and
encrypted credentials hash (encryptedUserCredentialsHash) in
privatePasswordLeakVerification. If the verdict (leakedPasswordVerdict)
indicates compromised credentials, require a password reset or trigger a
step-up MFA challenge.
Use score-based keys and step-up MFA
When the ATO risk score
(accountDefenderAssessment.accountTakeoverVerdict.risk) or bot score
(riskAnalysis.score) indicates elevated risk, use score-based keys to trigger
step-up authentication or multi-factor authentication (MFA) in your application
as your enforcement mechanism. For example, prompt the user for an additional
factor, require re-authentication, or trigger one-time password (OTP)
verification.
To implement score-based keys and step-up MFA, complete the following steps:
Install score-based keys to collect session signals and detect automation in large-scale ATOs:
Web: Call
grecaptcha.enterprise.execute()on your web pages. For more information, see Install score-based keys on websites.Mobile: Call
execute()in the mobile SDKs. For more information, see Integrate Fraud Defense with Android apps or Integrate Fraud Defense with iOS apps.
When
accountTakeoverVerdict.riskexceeds your risk threshold orriskAnalysis.scorefalls below your bot threshold, trigger step-up authentication or an MFA challenge in your identity provider to verify account ownership on sign-in or for sensitive actions. Triggering step-up challenges selectively on elevated-risk requests reduces friction for legitimate users.
The following example shows how to integrate score-based keys in a sign-in workflow:
function submitForm() {
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute(
'reCAPTCHA_site_key', {action: 'account_login'}).then(function(token) {
document.getElementById("token").value = token;
document.getElementByID("loginForm").submit();
});
});
}<form id="loginForm" action="?" method="POST"> Username: <input type="text" name="username"/><br/> Password: <input type="password" name="password"/><br/> <input type="hidden" id="token" name="recaptcha_token"/> <button onclick="submitForm()">Login</button> </form>
<script src="https://www.google.com/recaptcha/enterprise.js" async defer></script>
You can experiment with this code in JSFiddle by clicking the <> icon in the
top-right corner of the code window.
<html>
<head>
<title>Account Login - Score</title>
<script src="https://www.google.com/recaptcha/enterprise.js"></script>
<script>
function submitForm() {
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute(
'reCAPTCHA_site_key', {action: 'account_login'}).then(function(token) {
document.getElementById("token").value = token;
document.getElementByID("loginForm").submit();
});
});
}
</script>
</head>
<body>
<form id="loginForm" action="?" method="POST">
Username: <input type="text" name="username"/><br/>
Password: <input type="password" name="password"/><br/>
<input type="hidden" id="token" name="recaptcha_token"/>
<button onclick="submitForm()">Login</button>
</form>
</body>
</html>What's next
- To learn about other account protection features, see User accounts protection features.