Skip to main content

Issue with Google ReCaptcha Password Leak API

  • August 1, 2023
  • 7 replies
  • 40 views

Forum|alt.badge.img+1

Hi, I am trying to follow instructions to embed the Google Recaptcha Password Leak check API into my application. https://cloud.google.com/recaptcha-enterprise/docs/check-passwords

The code works fine, but I always get true response for the leak check.. no matter what username and password I try, it always says it is compromised. Has anyone tried this API? am I missing something?

7 replies

Forum|alt.badge.img
  • New Member
  • August 12, 2023

@nabbasi_1  I am also facing the same issue, any workaround?


Forum|alt.badge.img
  • Bronze 1
  • October 4, 2023

Same here. Here is a code sample written in NestJs as a validator that replicates the problem.

 

@ValidatorConstraint({ name: "IsGoodPassword" }) export class IsGoodPasswordConstraint implements ValidatorConstraintInterface { private readonly logger = new Logger("IsGoodPasswordConstraint"); protected client: RecaptchaEnterpriseServiceClient = new RecaptchaEnterpriseServiceClient(); async validate(password: string, args: ValidationArguments) { const username = args.object["username"]; const verification: PasswordCheckVerification = await PasswordCheckVerification.create(username, password); const lookupHashPrefix: string = Buffer.from( verification.getLookupHashPrefix() ).toString("base64"); const encryptedUserCredentialsHash: string = Buffer.from( verification.getEncryptedUserCredentialsHash() ).toString("base64"); const credentials: google.cloud.recaptchaenterprise.v1.IPrivatePasswordLeakVerification = await this.createPasswordLeakAssessment( lookupHashPrefix, encryptedUserCredentialsHash ); const reencryptedUserCredentialsHash: Uint8Array = Buffer.from( credentials.reencryptedUserCredentialsHash!.toString(), "base64" ); const encryptedLeakMatchPrefixes: Uint8Array[] = credentials.encryptedLeakMatchPrefixes!.map(prefix => { return Buffer.from(prefix.toString(), "base64"); }); const status = verification.verify(reencryptedUserCredentialsHash, encryptedLeakMatchPrefixes); console.log("STATUS:", status); console.log(`Credential leaked: ${status.areCredentialsLeaked()}`); return !status.areCredentialsLeaked(); } async createPasswordLeakAssessment( lookupHashPrefix: string, encryptedUserCredentialsHash: string ): Promise<google.cloud.recaptchaenterprise.v1.IPrivatePasswordLeakVerification> { const createAssessmentRequest: google.cloud.recaptchaenterprise.v1.ICreateAssessmentRequest = { parent: `projects/**censored**`, assessment: { privatePasswordLeakVerification: { lookupHashPrefix, encryptedUserCredentialsHash } } }; const [response] = await this.client.createAssessment( createAssessmentRequest ); if (!response?.privatePasswordLeakVerification) { this.logger.error(response); throw new InternalServerErrorException( "Error obtaining response from reCaptcha" ); } return response.privatePasswordLeakVerification; } } export function IsGoodPassword( username?: string, validationOptions?: ValidationOptions ) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return function (object: any, propertyName: string) { registerDecorator({ target: object.constructor, propertyName: propertyName, constraints: [username], options: { message: `${propertyName} was compromised`, ...validationOptions }, validator: IsGoodPasswordConstraint }); }; }

 


Forum|alt.badge.img

Also facing the same issue. @nabbasi_1 @PloggCTO were either of you able to identify the root cause/the bug?


Forum|alt.badge.img
  • Bronze 1
  • December 1, 2023

Also facing the same issue. @nabbasi_1 @PloggCTO were either of you able to identify the root cause/the bug?


No news on that unfortunately.


Forum|alt.badge.img+1
  • Author
  • New Member
  • December 8, 2023

Also facing the same issue. @nabbasi_1 @PloggCTO were either of you able to identify the root cause/the bug?


No, no solution yet.. 


Forum|alt.badge.img

No, no solution yet.. 


By the way, using the sample code from this repo seemed to do the trick.


Forum|alt.badge.img
  • Bronze 1
  • December 8, 2023

By the way, using the sample code from this repo seemed to do the trick.


Thanks, will look at it ASAP.