The importance of securing your DataVault Connect implementation
At TARTLE, data security is our number one priority, and we demand the highest standards from ourselves and our partners. This guide is designed to help you secure your DataVault Connect implementation by providing a list of best practices.
PKCE to prevent interception of authorization codes
Our OAuth 2.0 implementation uses the PKCE (Proof Key for Code Exchange, pronounced "pixy") extension to prevent authorization code interception attacks.
PKCE works by having the client create a cryptographically random string (the "code verifier") and then sending a derived value (the "code challenge") during the authorization request. Later, when exchanging the authorization code for tokens, the client proves possession of the original code verifier, ensuring that only the legitimate client can exchange authorization codes. For more in depth details about PKCE, check the external resources.
As a TARTLE integration partner, here's what you need to implement for PKCE:
- Generate a cryptographically random code verifier.
function generateCodeVerifier() {
// Create a cryptographically random string between 43-128 characters
const array = new Uint8Array(64) // 64 bytes → 64*8 = 512 bits
crypto.getRandomValues(array)
// Convert to base64url encoding
return base64UrlEncode(array)
}
function base64UrlEncode(array) {
return btoa(String.fromCharCode.apply(null, array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
}
- Create a code challenge
async function generateCodeChallenge(codeVerifier) {
// SHA-256 hash the code verifier
const encoder = new TextEncoder()
const data = encoder.encode(codeVerifier)
const digest = await crypto.subtle.digest('SHA-256', data)
// Convert digest to base64url encoding
return base64UrlEncode(new Uint8Array(digest))
}
- Save the code verifier in a secure location.
The code verifier must be stored securely from the time of the authorization request until the token exchange.
Depending on your application type, you might want to create and store the code verifier and challenge on the server or the client, there are many ways of doing this, our recommended way is:
- Create the code verifier and challenge on the server and save the verifier in a
secure
,httpOnly
,samesite=strict
cookie. - Pass the code challenge to the page that will build your DataVault Connect button (alongside the client_id and redirect_uri).
- When the user is redirected to your callback url, your server will be able to retrieve the verifier from the cookie to verify the challenge.
Saving code verifier securely
document.cookie = `pkce_code_verifier=${codeVerifier}; path=/; secure; httpOnly; samesite=strict`
- Send the code challenge in the authorization request.
Use this code to help you build the authorization url with the code challenge and code verifier.
State to avoid CSRF attacks
The state parameter is used to prevent CSRF attacks. It is a random string that is sent to the authorization server and back to the client.
The principle is similar to PKCE, but instead of using a code verifier to verify a challenge, you will use a cryptographically random string and verify that the one you sent to the authorization page is the same as the one you received back in the callback. For more details on how this helps you avoid CSRF attacks, check the external resources.
- Generate a cryptographically random state.
Generating a cryptographically random state
const array = new Uint8Array(32) // 256 bits of randomness
window.crypto.getRandomValues(array)
const state = Array.from(array, (byte) =>
byte.toString(16).padStart(2, '0'),
).join('')
- Save the state securely.
Saving state securely
document.cookie = `pkce_state=${state}; path=/; secure; httpOnly; samesite=strict`
Use this value to help you build the authorization url with the code challenge and code verifier.
External Resources
RFC 6749 Section 4.1.1
The section of the OAuth 2.0 specification that describes the authorization request parameters