Mitigate Replay Attacks When Using the Implicit Flow
To mitigate replay attacks in the Implicit Flow with Form Post, applications must use a nonce
as outlined by the OpenID Connect (OIDC) specification.
The nonce
is generated by the application, sent as a query string parameter in the authentication request, and included in the ID Token response from Login 3.0. This enables the application to verify the correlation between the authentication request and the ID Token response.
For details on where to include the nonce
, refer to Implementing Login with Implicit Flow in Login 3.0.
Generate a Cryptographically Random Nonce
To generate a secure nonce
, you can use tools like Nano ID or the Web Crypto API provided by modern browsers. Here’s an example using the Web Crypto API:
function randomString(length) {
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz+/';
let result = '';
while (length > 0) {
const bytes = new Uint8Array(16);
const random = window.crypto.getRandomValues(bytes);
random.forEach((c) => {
if (length === 0) return;
if (c < charset.length) {
result += charset[c];
length--;
}
});
}
return result;
}
Persist Nonces Across Requests
The generated nonce
must be stored securely in your application for later validation. You can use one of the following methods:
HttpOnly Session Cookies (recommended for server-side apps).
HTML5 Local Storage (for client-side apps).
For example:
window.localStorage.setItem('nonce', randomString(16));
Validate the ID Token
After Login 3.0 responds with an ID Token, validate and decode the token as usual. Ensure that the nonce
claim in the token matches the value sent in the original request. If the nonce
doesn’t match, reject the authentication response to prevent potential token replay attacks.
const jwt = '...'; // Decoded ID Token body
if (jwt.nonce === window.localStorage.getItem('nonce')) {
// Nonce is valid
} else {
// Nonce is invalid! Potential token replay attack
}
Last updated
Was this helpful?