This document outlines security best practices for integrating the Spreedly Web SDK to maintain PCI DSS compliance and protect against common web vulnerabilities.
- Security Features
- Secure Integration Checklist
- Subresource Integrity (SRI)
- Release Verification
- Security Support
The Spreedly Web SDK includes built-in security controls:
- Isolated iFrames — Card data is captured inside Spreedly-hosted iframes and never touches your DOM or JavaScript context.
- Automatic CVV TTL — CVV values are automatically cleared from memory after 3 minutes or after tokenization, whichever comes first.
- Input Validation — Real-time Luhn checks, card type detection, and format validation run inside the iframe before any API call.
- Tokenization Throttling — Built-in rate limiting prevents rapid-fire tokenization attempts.
- No Card Data Storage — No card data is stored in memory, localStorage, cookies, or any persistent browser storage.
- Origin Validation — All cross-frame
postMessagecommunication validates the sender's origin. - SRI Support — Integrity hashes are published for every release, enabling browser-enforced file verification.
- HTTPS Only — The SDK enforces secure connections in production.
Always use the integrity attribute when loading the SDK to ensure the file hasn't been tampered with:
Hosted Fields:
<script
src="https://core.spreedly.com/checkout/sdk/{version}/index.js"
integrity="sha384-{HASH_FROM_SRI_MANIFEST}"
crossorigin="anonymous"
></script>Express Checkout:
<script
src="https://core.spreedly.com/checkout/elements/{version}/express-checkout.js"
integrity="sha384-{HASH_FROM_SRI_MANIFEST}"
crossorigin="anonymous"
></script>See Subresource Integrity (SRI) below for how to obtain the hashes.
Add the following directives to your page's CSP header or meta tag. The SDK loads iframes and scripts from core.spreedly.com and sends telemetry data to Datadog for monitoring.
Content-Security-Policy:
script-src 'self' https://core.spreedly.com;
frame-src https://core.spreedly.com;
child-src https://core.spreedly.com;
connect-src 'self' https://core.spreedly.com https://pci.browser-intake-datadoghq.com;Meta tag alternative:
<meta http-equiv="Content-Security-Policy" content="
script-src 'self' https://core.spreedly.com;
frame-src https://core.spreedly.com;
child-src https://core.spreedly.com;
connect-src 'self' https://core.spreedly.com https://pci.browser-intake-datadoghq.com;
">Note on connect-src: The pci.browser-intake-datadoghq.com domain is required because the SDK sends anonymized telemetry (load times, error rates) to Datadog for operational monitoring. No card data is included in telemetry.
Additional CSP for offsite payments: If you're using Braintree APM or Stripe APM, you'll also need to allow their respective domains. See the integration guides for Braintree and Stripe APM.
The SDK requires HTTPS in production. HTTP connections will fail.
https://yoursite.com/checkout ← allowed
http://yoursite.com/checkout ← blocked
Clickjacking attacks trick users into interacting with hidden elements by overlaying your payment page with a malicious frame. Protect your checkout pages with these measures:
Prevent your payment pages from being embedded in third-party iframes:
X-Frame-Options: DENYOr, to allow only your own domain:
X-Frame-Options: SAMEORIGINThe modern replacement for X-Frame-Options (use both for broader browser support):
Content-Security-Policy: frame-ancestors 'self';Or to block all framing:
Content-Security-Policy: frame-ancestors 'none';Add this to your checkout page as an additional protection layer:
if (window.self !== window.top) {
window.top.location = window.self.location;
}| Risk | Mitigation |
|---|---|
| Payment page embedded by attacker | Use X-Frame-Options: DENY or frame-ancestors 'none' |
| UI redressing attacks | Ensure checkout forms are not visually overlayable |
| Transparent iframe overlay | Set proper z-index and use frame-busting scripts |
| Cross-origin frame communication | SDK validates all postMessage origins internally |
Note: The Spreedly SDK's hosted iframes have their own CSP and origin validation. These recommendations apply to your checkout page that embeds the SDK.
Subresource Integrity ensures that files loaded from CDNs haven't been tampered with. The browser computes a hash of the downloaded file and compares it to the expected hash in the integrity attribute. If they don't match, the browser refuses to execute the script.
Each release publishes an sri-manifest.json file on the CDN:
Hosted Fields:
https://core.spreedly.com/checkout/sdk/{version}/sri-manifest.json
Express Checkout:
https://core.spreedly.com/checkout/elements/{version}/sri-manifest.json
The manifest contains hashes in both SHA-384 and SHA-512:
{
"version": "{version}",
"generatedAt": "2026-01-15T10:30:00.000Z",
"algorithm": "sha384 (recommended) and sha512 (alternative)",
"assets": [
{
"file": "index.js",
"url": "https://core.spreedly.com/checkout/sdk/{version}/index.js",
"sri": {
"sha384": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/...",
"sha512": "sha512-..."
}
}
]
}Use the sha384 value — it provides optimal security with broad browser support.
<script
src="https://core.spreedly.com/checkout/sdk/{version}/index.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/..."
crossorigin="anonymous"
></script>Open DevTools → Network → select the script → check:
- Status: 200
- No console errors about integrity mismatch
If the integrity check fails, the browser will block the script and log an error to the console.
For additional assurance beyond SRI, each release includes artifacts for manual verification:
Every release publishes a release-manifest.json with SHA-256 checksums for all assets:
https://core.spreedly.com/checkout/sdk/{version}/release-manifest.json
https://core.spreedly.com/checkout/elements/{version}/release-manifest.json
{
"version": "{version}",
"buildDate": "2026-01-15T10:30:00.000Z",
"assets": [
{
"file": "index.js",
"size": 88002,
"sha256": "a1b2c3d4e5f6...",
"url": "https://core.spreedly.com/checkout/sdk/{version}/index.js"
}
],
"checksumAlgorithm": "SHA-256"
}VERSION="{version}"
# Download the manifest and asset
curl -O "https://core.spreedly.com/checkout/sdk/${VERSION}/release-manifest.json"
curl -O "https://core.spreedly.com/checkout/sdk/${VERSION}/index.js"
# Compute SHA-256
CALCULATED=$(shasum -a 256 index.js | awk '{print $1}')
EXPECTED=$(jq -r '.assets[] | select(.file=="index.js") | .sha256' release-manifest.json)
if [ "$CALCULATED" = "$EXPECTED" ]; then
echo "Verification passed"
else
echo "Verification failed — do not use this file"
fiEach release includes sbom.json (CycloneDX format) listing all bundled dependencies:
https://core.spreedly.com/checkout/sdk/{version}/sbom.json
https://core.spreedly.com/checkout/elements/{version}/sbom.json
Use this for dependency auditing, vulnerability scanning, and license compliance.
If you have security concerns or need assistance:
- Help Center: Submit a request to open a ticket with our Customer Support team.
- Trust Center: For security or compliance-related issues, email security@spreedly.com or visit our Security & Compliance page.