Content Security Policy
The Content Security Policy (CSP) is a security standard introduced to prevent various attacks, including Cross-Site Scripting (XSS) and data injection attacks. It allows web developers to specify the domains the browser should consider valid sources of executable scripts for a given webpage.
By doing this, CSP can effectively reduce the risk of XSS attacks by specifying which sources are trusted, preventing browsers from executing scripts not approved as part of the policy.
If you choose to utilize CSP with Descope Flows, below is an example of a valid CSP configuration, including the necessary references to static.descope.com.
If you're using Descope with a private tenant, then you will need to request a specific CSP policy from Descope support directly.
Customers without Custom Domain
<meta
http-equiv="Content-Security-Policy"
content="connect-src 'self' static.descope.com api.descope.com;
style-src 'self' 'unsafe-inline' fonts.googleapis.com 'nonce-${nonce}';
img-src 'self' static.descope.com data:;
font-src fonts.gstatic.com descopecdn.com data:;
script-src 'self' descopecdn.com static.descope.com cdn.jsdelivr.net 'nonce-${nonce}';"
/>Customers with Custom Domain
In this example, the CNAME record is configured to be auth.example.com, with the App URL being https://example.com.
<meta
http-equiv="Content-Security-Policy"
content="connect-src 'self' auth.example.com;
style-src 'self' 'unsafe-inline' fonts.googleapis.com 'nonce-${nonce}';
img-src 'self' auth.example.com data:;
font-src fonts.gstatic.com descopecdn.com data:;
script-src 'self' descopecdn.com static.descope.com cdn.jsdelivr.net 'nonce-${nonce}';"
/>Nonce Support
Nonce, or "number used once," is a cryptographically secure, random value generated by the server for each unique HTTP request.
To use nonce, add it to the Descope flow component as seen below:
const hdrs = await headers();
const nonce = hdrs.get("x-nonce");
return (
<Descope flowId="sign-up-or-in" nonce={nonce!} />
); const hdrs = await headers();
const nonce = hdrs.get("x-nonce");
return (
<Descope flowId="sign-up-or-in" nonce={nonce!} />
);// .Controller file
app.controller('AuthController', function($http, $scope) {
$http.get('/headers-endpoint') // Replace with the actual endpoint providing the headers
.then(function(response) {
const nonce = response.headers('x-nonce');
$scope.nonce = nonce;
})
.catch(function(error) {
console.error('Failed to fetch headers:', error);
});
});
//.html file
<descope flowId="sign-up-or-in" nonce="{{nonce}}"></><template>
<Descope flowId="sign-up-or-in" v-if="nonce" :nonce="nonce" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Descope from '@descope/vue-sdk' // Adjust path as needed
const nonce = ref(null)
onMounted(async () => {
const response = await fetch('/headers-endpoint') // Adjust endpoint
const headerNonce = response.headers.get('x-nonce')
nonce.value = headerNonce
})
</script>You can refer to this sample application which demonstrates proper nonce implementation in a CSP context.
Your CSP will need to include these references in order to effectively use flows without browser errors.