captcha icon indicating copy to clipboard operation
captcha copied to clipboard

Secure verify endpoint on providers

Open forgetso opened this issue 1 year ago • 0 comments

We need to secure the verify endpoint on providers so that we can rate limit it and realistically implement charges different pricing tiers.

Background

Captcha Providers run an API that delivers our service. There are various endpoints:

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/types/src/provider/api.ts#L18-L27

Clients are billed based on how many requests they make to verify endpoints:

  • 0 - 100k Free
  • 100k - 1M $9 per month
  • 1M+ - custom

To make a request to an endpoint, a client must pass their dapp (site key - which is actually the public key of a keypair).

Clients' obtain their site key from us when they sign up to our website. We email them their site key as part of our email trigger server. However, we don't currently provide access to the private key.

Precursor

Access to the private key must also be provided - a precursor to merging this issue.

Problem

Currently, there is no check in the verify endpoints to verify that the calling dapp (site key) is actually owned by the caller.

Image Captcha verification body

dapp is passed but there is no check to see if the caller owns the dapp (site key) account.

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/types/src/provider/api.ts#L97-L103

parsed.dapp is not used in this verify function:

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/provider/src/api/captcha.ts#L137-L140

PoW captcha verification body

dapp is passed but there is no check to see if the caller owns the dapp (site key) account.

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/types/src/provider/api.ts#L146-L149

dapp is not used in this verify function:

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/provider/src/api/captcha.ts#L248

Considerations

Frontend Verify Calls

There is currently a verify API call made from the frontend of procaptcha when a user has cached @prosopo/procaptcha local storage, indicating that they previously completed a captcha.

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/procaptcha/src/modules/Manager.ts#L184-L196

These calls would need to be switched to use a different, unsecured endpoint as we obviously can't give the frontend access to the dapp private key.

API Verify Endpoint

Calls are made from an AWS lambda on behalf of dapps. Dapp signatures would also need to be forwarded on from this lambda to the providers. Or, signature verification could occur within the lambda to avoid making any extra unnecessary calls should the signature be invalid.

Required Changes

Require that dapps calling the verify endpoints sign a message to show that they own their site key. This needs to occur in the following places:

Where to add signature

Add dapp signature parameter here: https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/api/src/api/ProviderApi.ts#L76-L82

Add dapp signature parameter here: https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/api/src/api/ProviderApi.ts#L103-L108

How to compute a signature

Here is an example of how signing is achieved in the frontend using the user's account:

https://github.com/prosopo/captcha/blob/60c44b46240edae78319bc6af1a2b5b5b1cdffa2/packages/procaptcha/src/modules/ProsopoCaptchaApi.ts#L136-L141

We need to provide similar functionality wherever the verify endpoints are called.

What message to sign

TODO - this needs to be something that is fairly recent so that the same signature cannot be used again and again. The block number might be a good candidate.

forgetso avatar May 01 '24 09:05 forgetso