Most websites score a C or D on a security audit not because the team doesn't care, but because the fixes look intimidating and the reports are full of jargon. The good news: about 80% of the points you're missing come from a handful of misconfigurations that take minutes to fix once you know what to change.
Here's a breakdown of what actually moves a security score from a D to an A, in the order I'd tackle them on a real client site.
Start with the cheapest wins: HTTP security headers
Headers are the lowest-effort, highest-impact fixes. They're a single config change in Nginx, Apache, Cloudflare, or your framework — no code rewrites required.
The headers that actually count
- Strict-Transport-Security — Forces HTTPS for future visits. Use
max-age=31536000; includeSubDomains; preload. - Content-Security-Policy — The biggest single contributor to a top grade. More on this below.
- X-Content-Type-Options: nosniff — Prevents MIME sniffing attacks. One line.
- Referrer-Policy: strict-origin-when-cross-origin — Stops leaking URLs to third parties.
- Permissions-Policy — Disables browser features you don't use (camera, microphone, geolocation, etc.).
- X-Frame-Options: DENY — Or use
frame-ancestorsin your CSP instead.
Example Nginx snippet:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;That single block typically lifts a site from D to B on most scanners.
Tackle Content-Security-Policy properly
CSP is where most developers give up. The trick is to build it in report-only mode first, then enforce.
A workable starting CSP
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://www.google-analytics.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self';Deploy that, watch your browser console (or a reporting endpoint) for a week, then add legitimate sources to the allowlist. Once violations stop, switch the header name to Content-Security-Policy.
Avoid the common CSP mistakes
- Don't use
'unsafe-inline'for scripts. Refactor inlineonclick=handlers into external files, or use nonces. - Don't allow
*inscript-src. That's a free pass for any attacker. - Don't forget
frame-ancestors. It supersedesX-Frame-Optionsin modern browsers. - Don't ship without testing third parties. Stripe, Intercom, GTM, and Hotjar all need explicit allowlisting.
Lock down your cookies
Every cookie your site sets should have three attributes. If even one is missing, scanners will dock points and — more importantly — attackers can exploit it.
- Secure — Only sent over HTTPS.
- HttpOnly — Not accessible to JavaScript (prevents XSS cookie theft).
- SameSite=Lax (or
Strict) — Mitigates CSRF.
In Express:
res.cookie('session', token, { secure: true, httpOnly: true, sameSite: 'lax' });Check session cookies, CSRF tokens, and any analytics cookies you control. Third-party cookies from embedded widgets are out of your control, but your own should be airtight.
Fix your TLS configuration
HTTPS isn't binary. A valid certificate doesn't mean your TLS setup is strong.
What scanners look at
- TLS 1.2 minimum, ideally TLS 1.3 enabled
- No support for SSLv3, TLS 1.0, or TLS 1.1
- Strong cipher suites only (no RC4, no 3DES, no CBC where avoidable)
- Certificate chain complete (intermediate certs served)
- OCSP stapling enabled
- HSTS preload submission (optional but rewarded)
If you're on Cloudflare or a modern host, this is usually one toggle. If you're managing your own Nginx, run openssl s_client -connect yoursite.com:443 and compare against Mozilla's SSL configuration generator.
DNS hygiene most teams forget
DNS records are increasingly part of security scoring because they prevent email spoofing and subdomain takeovers.
The records to add
- CAA — Specifies which CAs can issue certs for your domain. Stops rogue issuance.
- SPF — Even if you don't send mail, set
v=spf1 -allto block spoofing. - DMARC — Start with
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.comto monitor, then move top=reject. - DKIM — Configured at your mail provider, but verify it's published.
Also audit dangling CNAMEs. A subdomain pointing at a decommissioned Heroku app or S3 bucket is a classic takeover vector.
Get CORS right
If your site exposes APIs, CORS misconfiguration is a common scorer killer. The two patterns that fail audits:
Access-Control-Allow-Origin: *combined withAccess-Control-Allow-Credentials: true— browsers reject this, but scanners flag it as a sign of confusion.- Reflecting the
Originheader without an allowlist — effectively allows any site to make authenticated requests.
Maintain an explicit list of allowed origins server-side, and only echo the origin back if it matches.
Audit your third-party scripts
Every external <script src=> is a trust relationship. If that CDN gets compromised, so does your site. Use Subresource Integrity (SRI):
<script src="https://cdn.example.com/lib.js" integrity="sha384-..." crossorigin="anonymous"></script>Tools like WebSentry flag scripts loaded without SRI so you can spot gaps quickly. If a third-party script can't be pinned (because it changes frequently), consider self-hosting a vetted copy or loading it from a sandboxed iframe.
The order I'd actually do this in
- Add the five core security headers (15 minutes)
- Fix cookie flags (20 minutes)
- Verify TLS configuration and disable old protocols (30 minutes)
- Add DNS records: CAA, SPF, DMARC (30 minutes)
- Deploy CSP in report-only mode (1 hour, then a week of tuning)
- Audit CORS and third-party scripts (varies)
- Re-scan, fix remaining warnings, enforce CSP
That sequence takes most sites from a failing grade to an A within a week, with the bulk of the gain happening on day one.
Measure, don't guess
Security scoring is only useful if you re-run it after every deploy. Headers get accidentally stripped by reverse proxies, cookies get added by new libraries, and CSP breaks the moment marketing adds a new tracking pixel. Run a scan at websentry.dev against your staging environment before pushing, and again against production after. The free scan grades SSL, headers, CSP, cookies, DNS, and CORS in one pass — which is the fastest way to confirm a fix actually landed.
Check your own site
Run a free security scan and see if your site has the issues covered in this article. Results in under 30 seconds.