Skip to content

Approov API Threat Protection integration with hCaptcha for Web Apps

Notifications You must be signed in to change notification settings

approov/web-quickstart-hcaptcha-javascript

Repository files navigation

Approov Quickstart: Web - Javascript - hCaptcha

This quickstart is for Javascript web apps that are using the hCaptcha service and that you wish to protect with Approov. If this is not your situation then please check if there is a more relevant quickstart guide available.

This quickstart provides the basic steps for integrating Approov into your web app. A more detailed step-by-step guide using a Shapes App Example is also available.

To follow this guide you should have received an onboarding email for a trial or paid Approov account.

ADDING THE APPROOV WEB SDK

The Approov web SDK can be downloaded using the Approov command line tool (see the installation instructions). Use the following command to download the latest web SDK package:

approov sdk -packageID approov.js.zip -getClientPackage approov.js.zip

This writes the latest available web SDK package to the approov.js.zip file (or any path that you specify). Unzip the file and copy the resulting Approov web SDK Javascript file, approov.js, into your project and load it as part of your web app:

<script type="module" src="./approov.js"></script>

USING THE APPROOV WEB SDK

Add the following code to your app implementation to import the Approov web SDK:

import { Approov, ApproovError, ApproovFetchError, ApproovServiceError, ApproovSessionError } from "./approov.js"

Add this function which initializes the Approov SDK, gets an hCaptcha token and requests an Approov token as required:

async function fetchApproovToken(api) {
  try {
    // Try to fetch an Approov token
    let approovToken = await Approov.fetchToken(api, {})
    return approovToken
  } catch (error) {
    if (error instanceof ApproovSessionError) {
      // If Approov has not been initialized or the Approov session has expired, initialize and start a new one
      await Approov.initializeSession({
        approovHost: 'web-1.approovr.io',
        approovSiteKey: 'your-Approov-site-key',
        hcaptchaSiteKey: 'your-hCaptcha-site-key',
      })
      // Get a fresh hCaptcha token
      const hcaptchaToken = await hcaptcha.execute({async: true})
      // Fetch the Approov token
      let approovToken = await Approov.fetchToken(api, {hcaptchaToken: hcaptchaToken})
      return approovToken
    } else {
      throw error
    }
  }
}

Customize the function using your Approov site key and hCaptcha site key to replace your-Approov-site-key and your-hCaptcha-site-key, respectively.

Finally, modify the location in your code that generates the request headers to include an Approov token, for example change your function that includes an hCaptcha token in the headers, to fetch and include an Approov token instead:

async function addRequestHeaders() {
  let headers = new Headers()
  // Add some headers here
  // ...
  // Then fetch and add the Approov token
  try {
    let approovToken = await fetchApproovToken('your-API-domain')
    headers.append('Approov-Token', approovToken)
  } catch (error) {
    console.error(error)
  }
  return headers
}

Customize the function above by using the domain you would like to protect with Approov in place of your-API-domain.

ERROR TYPES

The Approov.fetchToken function may throw specific errors to provide additional information:

  • ApproovFetchError Any error thrown by the fetch call made to perform a request to the Approov service. This indicates that there was a communication or network issue.
  • ApproovServiceError An error reported by the Approov service, such as missing or malformed elements in the underlying request. The errors property contains additional information.
  • ApproovSessionError The Approov session has not been initialized or has expired. A call to Approov.initializeSession should be made.
  • ApproovError Any other error thrown during an Approov web SDK call.

SETTING UP API PROTECTION

To actually protect your APIs there are some further steps:

  • The Approov service needs to be set up to provide tokens for your API.
  • Your API server needs to perform an Approov token check in addition to the steps in this frontend guide. Various Backend API Quickstarts are available to suit your particular situation depending on the backend technology used.

APPROOV SERVICE SETUP

The Approov service setup steps require access to the Approov CLI, please follow the Installation instructions.

ADDING API DOMAINS

In order for the Approov service to provide Approov tokens for particular API domains it is necessary to inform Approov about these. Execute the following command to add and web-enable the domain, replacing your.domain with the name of your API domain that should be protected with Approov:

approov api -add your.domain -allowWeb

ADDING A HCAPTCHA SITE

A hCaptcha site can be added by by providing a valid site key and associated secret. The following command adds a site leaving all other settings at their default values:

approov web -hcaptcha -add your-hCaptcha-site-key -secret your-hCaptcha-secret

To change a site's properties you simply add it again with all the properties required for the changed subscription. Each addition of the same site key completely overwrites the previously stored entry.

You are now set up to request and receive Approov tokens.

CHECKING IT WORKS

Your Approov onboarding email should contain a link allowing you to access Live Metrics Graphs. After you've run your web app with Approov integration you should be able to see the results in the live metrics within a minute or so.

The Approov CLI can check Approov token validity and display the claims. Open the browser developers tools and from the network tab grab the Approov token from the request header Approov-Token and then check it with:

approov token -check your-Approov-token

OTHER CONSIDERATIONS

When adding Approov with hCaptcha into your own web app you may want to address some of the following points:

API Domains

Remember to do an audit of your API to check which end-points should be enabled for web access. When necessary, extend the backend token check to differentiate between mobile app and web app tokens and use that to restrict the access to more sensitive end-points. Once the backend is ready, enable the Approov web protection by adding the -allowWeb flag whenever you register or re-register an API with the Approov CLI.

Changing Your API Backend

The Shapes example app uses the API endpoint https://shapes.approov.io/v3/shapes hosted on Approov's servers. You can find the code for it in this Github repo.

If you want to integrate Approov into your own web app you will need to integrate an Approov token check in the backend. Since the Approov token is simply a standard JWT this is usually straightforward.

Check the Backend API Quickstarts examples that provide a detailed walk-through for specific programming languages and frameworks.

Content Security Policy

In the content-src policy of your current web app you will need to add the domains for Approov:

connect-src https://your-domains.com https://web-1.approovr.io/;

hCaptcha works with an iframe therefore you need to allow it with:

frame-src https://newassets.hcaptcha.com/captcha/;

Finally, add the static and dynamic hCaptcha scripts to your script-src policy:

script-src 'self' https://hcaptcha.com/1/api.js https://newassets.hcaptcha.com/captcha/;

You can check the Content Security Policy for your site here or test it in conjunction with all the other security headers here.

FURTHER OPTIONS

Please also see the full documentation of the Approov Web Protection Integration.

Token Binding

If want to use Token Binding then pass the data to be used for binding as follows:

const payload = new TextEncoder().encode(data)
Approov.fetchToken(api, {hcaptchaToken: result, payload: payload}))

This results in the SHA-256 hash of the passed data to be included as the pay claim in any Approov tokens issued until a new value for the payload is passed to a call to Approov.fetchToken. Note that you should select a value that does not typically change from request to request, as each change requires a new Approov token to be fetched.