Back to Blog
JavaScript Snippet Security Checklist 2025
General

JavaScript Snippet Security Checklist 2025

Diwakar (Diwakar)
Diwakar (Diwakar)
May 21, 2025

🚨 Why this still matters

Remember the polyfill.io breach? Ten months later security firm Censys found 380 000+ sites still loading that poisoned file. Same year, Magecart skimmers hit thousands of stores. The latest Verizon DBIR logged 10 626 confirmed web-app breaches—a record.

If your project drops even one <script> tag into someone else’s page, you’re part of that attack surface. The checklist below is my personal guard-rail; steal it, share it, improve it.


1 – Content-Security-Policy in plain English

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.example.com;
  object-src 'none';
  base-uri  'none';
  report-uri /csp-report
  • Start “Report-Only”. Add Content-Security-Policy-Report-Only, watch browser reports for a week.

  • Tighten gradually. Block inline scripts; migrate risky attributes to script-src-attr. Chrome now flags these by default.

  • Log somewhere real. A /csp-report endpoint + simple dashboard is enough.

CSP is like a guest list—browsers refuse to run code from uninvited domains.


2 – Sub-Resource Integrity (SRI) 2-minute setup

<script src="https://cdn.example.com/widget.min.js"
        integrity="sha256-q0Aj...="
        crossorigin="anonymous"></script>
  • Guarantees the file the browser fetches is exactly the one you signed.

  • April 2025 SRI-2 draft extends this to JSON and module workers—good news for SPA devs.

  • Automate: add a GitHub Action that re-hashes files on every release and fails the build if the hash changes without a commit.


3 – Skip innerHTML, use textContent

// ❌ vulnerable
element.innerHTML = location.hash.slice(1);

// âś… safe
element.textContent = location.hash.slice(1);

Need rich HTML? Pass it through DOMPurify or a templating library that sanitises for you. Never trust user-supplied strings.


4 – Script tag vs sandboxed iframe

Inline <script>Sandboxed <iframe>
SEOGoodNot indexed
StylesInherits site CSSFully isolated
Performance1 requestExtra document, a bit slower
SecurityShares page originOwn origin + sandbox

Rule-of-thumb: if the widget handles untrusted input (chat widgets, third-party ads), wrap it in a sandboxed iframe and sleep better.


5 – Pin and verify your dependencies

  • Run npm audit signatures in CI—verifies package signatures.

  • Use Renovate or Dependabot to bump patches automatically.

  • Pin versions; wildcard ranges belong in 2019.


6 – Copy-paste checklist (print this ✂︎)

  1. Content-Security-Policy in Report-Only mode

  2. All external scripts have an SRI hash

  3. No inline JS unless whitelisted by CSP nonce

  4. Zero innerHTML writes from user data

  5. Sandboxed iframe for any third-party UI

  6. npm audit signatures passes

  7. Dependencies pinned by exact version

  8. CSP reports collected & reviewed weekly

  9. Run a quick grep to list every external script:

grep -oR '<script [^>]*src="[^"]*"' .
  1. Re-scan after every major dependency update

7 – Share your war stories 👋

Did these steps save your bacon? Got an extra trick? Tag me on X/Twitter or Indie Hackers—I'll update the list and credit you.

Stay safe, ship fast, and give your future self fewer 3 a.m. incident calls. 🙌