# Website security checklist: CSP, HSTS, headers

> A website security checklist for marketing sites: HTTPS and HSTS, a working Content Security Policy, the other headers that matter, forms and dependencies.

Canonical page: https://kyvrel.com/blog/website-security-checklist
Published: 2025-09-02 · 6 min read · Kyvrel

This website security checklist covers the controls that protect a typical marketing site: HTTPS with HSTS, a Content Security Policy, a short set of response headers, safe forms and cookies, locked-down admin access, and patched dependencies. None of it is exotic. Most of it is configuration you set once and then test after every release.

Marketing sites rarely hold payment data, so teams assume they are low-risk. They still collect leads, run third-party scripts and carry your brand. A defaced homepage or a skimmed contact form is a real incident.

## Why does a marketing site need a security checklist?

Attackers rarely target a small company's website by hand. They scan millions of sites for known weaknesses and exploit whatever they find. An outdated plugin, an exposed admin panel or a missing header is enough.

The usual outcomes are unglamorous but costly:

- **Injected scripts** that redirect visitors, mine cryptocurrency or steal form data.
- **Spam pages** added to your domain, which can damage search rankings.
- **Leaked leads** from forms that store data insecurely or send it to the wrong place.
- **Account takeover** of the CMS through reused passwords.

A short, enforced checklist removes most of this risk. It also gives you clear answers when a client's security team sends a questionnaire.

![Layered shield showing transport security, headers, forms and dependencies as separate defensive layers](https://kyvrel.com/blog/inline/website-security-checklist-1.png)

## Transport: HTTPS everywhere, then HSTS

Every page, asset and API call should load over HTTPS. Redirect plain HTTP to HTTPS with a permanent redirect, and fix any mixed-content warnings.

Then add HTTP Strict Transport Security. HSTS tells browsers to use HTTPS for your domain for a set period, even if someone types `http://` or follows an old link.

```
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
```

Roll it out in steps. Start with a short `max-age`, such as one day, and confirm nothing breaks on any subdomain. Then raise it to one or two years. Only add `preload` and submit the domain to the browser preload list once you are sure every subdomain supports HTTPS. Removal from the list takes a long time.

## Content Security Policy that actually works

A Content Security Policy (CSP) tells the browser which sources may run scripts, load styles, embed frames and send data. It is the strongest defense against cross-site scripting, because injected code is blocked even if it reaches the page.

The modern approach is a strict, nonce-based policy rather than a long allowlist of domains:

```
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{random}' 'strict-dynamic';
  style-src 'self' 'nonce-{random}';
  img-src 'self' data: https:;
  connect-src 'self';
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
  object-src 'none';
  upgrade-insecure-requests
```

The server generates a fresh random nonce for each response and adds it to every script tag it trusts. `'strict-dynamic'` lets those trusted scripts load their own dependencies. Anything injected without the nonce does not run.

How to introduce CSP without breaking the site:

1. **Start in report-only mode.** Send `Content-Security-Policy-Report-Only` and collect violation reports for a week or two.
2. **Inventory third parties.** Analytics, chat widgets, tag managers, embedded video. Each one needs a deliberate decision.
3. **Tighten, then enforce.** Fix or remove what the reports flag, then switch to the enforcing header.
4. **Watch after each release.** New features often add new sources.

A tag manager that lets marketing add arbitrary scripts works against CSP. Agree in advance who can add third-party code and how it gets reviewed.

The [MDN guide to Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) explains every directive in detail.

## The rest of the website security checklist: headers that matter

Beyond HSTS and CSP, a handful of headers close common gaps. The [OWASP Secure Headers Project](https://owasp.org/www-project-secure-headers/) keeps a maintained reference.

```
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin-Opener-Policy: same-origin
X-Frame-Options: DENY
```

- **X-Content-Type-Options: nosniff** stops browsers from guessing file types, which blocks a class of content-type attacks.
- **Referrer-Policy** limits how much of your URLs leak to other sites. `strict-origin-when-cross-origin` is a sensible default.
- **Permissions-Policy** switches off browser features your site never uses, such as the camera or location.
- **Cross-Origin-Opener-Policy** isolates your pages from windows opened by other sites.
- **X-Frame-Options** prevents clickjacking in older browsers. The CSP `frame-ancestors` directive does the same job in modern ones. Send both.

Skip `X-XSS-Protection`. It is deprecated, modern browsers ignore it, and in some older ones it caused problems of its own.

Also publish a `/.well-known/security.txt` file, defined in [RFC 9116](https://www.rfc-editor.org/rfc/rfc9116). It tells security researchers how to report a problem to you.

## Forms, cookies and admin access

Forms are where marketing sites handle personal data, so they deserve the same care as a login page.

- **Validate on the server.** Client-side checks help users. They do not protect you.
- **Rate-limit submissions.** Limit requests per IP to slow down spam and abuse.
- **Escape output.** Anything a visitor submits must be treated as text when it appears in emails, dashboards or the CMS.
- **Collect less.** Every field you do not need is data you do not have to protect.
- **Set cookie flags.** Session cookies need `Secure`, `HttpOnly` and a `SameSite` value.

For the CMS and hosting accounts:

- Turn on multi-factor authentication for every user.
- Give each person their own account with the lowest role they need.
- Remove access the day someone leaves the project.
- Keep admin panels off predictable public URLs where the platform allows it.

## Dependencies, hosting and secrets

Most compromises use known vulnerabilities that already have a fix. Patching is the least exciting item on this list and one of the most important.

- **Commit the lockfile.** Builds should install the exact versions you tested.
- **Automate update alerts.** Tools like Dependabot or Renovate flag vulnerable packages. Someone must own the review.
- **Patch the framework promptly.** In March 2025, Next.js disclosed [CVE-2025-29927](https://nvd.nist.gov/vuln/detail/CVE-2025-29927), a flaw that let attackers bypass authorization checks done in middleware. Patched releases shipped quickly. The risk sat with sites that did not update.
- **Keep secrets out of the repository.** API keys belong in the hosting platform's environment variables, never in code or in client bundles.
- **Back up content and test the restore.** A backup you have never restored is a hope, not a backup.

Your platform choice changes how much of this you carry. A plugin-heavy CMS means more third-party code to patch. A static or server-rendered stack has fewer moving parts but still needs dependency updates. That trade-off is worth weighing before you pick a stack.

If you are moving platforms anyway, put these checks into the migration plan from the start. Our guide to [website migration without losing SEO](https://kyvrel.com/blog/website-migration-seo) shows where they fit around launch.

## How to test your setup

![Flow of a security check: scan headers, review CSP reports, audit dependencies, retest after release](https://kyvrel.com/blog/inline/website-security-checklist-2.png)

1. Scan the site with [MDN HTTP Observatory](https://developer.mozilla.org/en-US/observatory) to check headers and TLS settings.
2. Open the browser console on key pages and look for CSP violations and mixed content.
3. Run your package manager's audit command and review the results.
4. Try the forms with unexpected input: long strings, HTML, repeated rapid submissions.
5. Repeat after every significant release. Security settings drift when nobody checks them.

## Next step: build it secure from the first commit

Every Kyvrel build, including our [web app and SaaS development](https://kyvrel.com/products/web-app) projects, ships with HTTPS, HSTS, a nonce-based CSP, the headers above, rate-limited forms and a `security.txt` file by default. A web app starts at $25,000 for an MVP with 15 screens, with a typical timeline of 12-16 weeks. Our 3-month care plan, $1,500, covers dependency updates and security patches after launch.

Still choosing a platform? Our [WordPress vs Next.js comparison](https://kyvrel.com/compare/wordpress-vs-nextjs) sets out what each one means for patching and long-term maintenance.
