Security and Content Security Policy
Which entries your Content Security Policy needs for the widget, why it works without an inline script and without unsafe-inline, how it is isolated from your page and which secrets never belong in the browser.
The Content Security Policy
The widget loads no third-party fonts, no tracking pixel and does not run eval. It sets its styles through constructable stylesheets (adoptedStyleSheets) in the shadow DOM; these are not covered by style-src. You therefore need no unsafe-inline and no unsafe-eval.
With the reactive.chat addresses:
Content-Security-Policy:
script-src 'self' https://cdn.reactive.chat;
connect-src 'self' wss://ws.reactive.chat https://ws.reactive.chat;
img-src 'self' data: https:;
With an own domain:
Content-Security-Policy:
script-src 'self' https://chat.your-company.com;
connect-src 'self' wss://chat.your-company.com https://chat.your-company.com;
img-src 'self' data: https:;
The individual entries:
- script-src – the location of
loader.js. The core (core.<hash>.js) and the modules loaded later (tours, privacy text, shop) come from there too. - connect-src with wss:// – the chat connection.
- connect-src with https:// – the same address once more: the HTTP fallback, the offline form, file uploads, the privacy text and Smart Answer run through it. If this entry is missing, you only notice in networks without WebSocket – there, no connection is established at all.
- img-src – images in the chat: logo and avatars (your
https://addresses ordata:images), images of the promo card and previews of attachments (from the chat address). If you want to narrowimg-src, include at least the chat address and the hosts of your logo and card images. The widget shows a blocked image as a file line instead of a preview.
Older browsers without constructable stylesheets (such as Safari before 16.4) fall back to a <style> element, which a strict style-src blocks. The widget works there, but unstyled.
No inline script needed
The installation consists only of a <script src> with attributes. Your own calls (identify, track, open) belong in your own script files or in an inline script with a nonce:
<script nonce="R4nd0mN0nc3">
ReactiveChat('identify', { userId: '4711', userHash: '…', exp: 1792503600 });
</script>
A template without an inline script is under Identifying visitors.
Subresource Integrity
loader.js has no version number in its name and is updated continuously; an integrity attribute would shut down the chat on the next update. The core is loaded with a content hash in its name (Architecture). If your policy requires SRI, serve loader.js yourself and set data-rc-ws-url (Quick start) – but then updating it is also up to you.
Isolation from your page
- Closed shadow DOM. Your styles do not reach the widget, and its styles do not reach your page – not even with global resets.
- No cookies. The widget sets no cookies; IDs are kept in the browser's storage, without consent only in
sessionStorage(Privacy integration). - No access to form fields. The page text for the assistant never reads input fields and does not run at all on pages such as account, checkout and cart. You exclude further areas with
data-rc-private. - Personal data is masked twice: in the browser before a message goes out (card numbers with Luhn check, IBAN, email, phone, tax numbers), and on the server before storage. Sensitive query parameters (
email,password,token,key,card…) are removed from transmitted addresses. - Links and images from messages and cards are restricted to
https://;javascript:anddata:links are discarded.
Origin check
The chat connection is only accepted from the domains listed in the project under Allowed origins (subdomains included). A third-party page that copies your site key gets origin_denied. If the list is empty, no check takes place – so always enter your domains. Details under Transport.
The site key itself is not a secret; it is in the source of every page.
What never belongs in the browser
- the identity secret (for
userHash) – Identity - the customer data endpoint secret
rckd_…– Customer data - the webhook signing secret – Webhooks
- API keys
rc_live_…– Server API - the proxy key
rcpx_…– Own domain
Nor in an app, a public repository or the address of a page.
Abuse protection
The server limits connections, frames and messages per connection and per address and blocks on repeated violations (close 1008). Behind your own proxy, it counts per visitor address only if the proxy key is correct – otherwise all visitors share the proxy's address. Figures under Limits and quotas.
Next: Own domain
آخرین بهروزرسانی: