What Happens When a React Library Gets a Security Audit
What Happens When a React Library Gets a Security Audit
Refine scored 38/F on the Security Headers & Basics audit. That is the lowest score in our benchmark dataset outside of example/starter apps. But Refine is a well-maintained React meta-framework with 30k+ GitHub stars, backed by a funded company, with active security practices.
So what happened?
The audit did its job (too well)
The Security Headers audit checks 20 things across four categories: Transport Security, Security Headers, Information Exposure, and Basic Hygiene. Here is what Refine's results look like:
Transport Security (30% weight):
- HTTPS enforced: fail
- HSTS enabled: fail
- Secure cookie flag: fail
- SameSite cookie attribute: fail
Security Headers (30% weight):
- CSP present: fail
- CSP no unsafe-inline: fail
- X-Frame-Options: fail
- X-Content-Type-Options: fail
- Referrer-Policy: fail
- Permissions-Policy: fail
Basic Hygiene (15% weight):
- .env in .gitignore: pass
- No hardcoded secrets: pass
- Lockfile present: pass
- security.txt: fail
Every transport and headers check fails. Every single one. And the audit is correct: there is no HTTPS enforcement, no HSTS, no CSP, no X-Frame-Options. These headers do not exist in the Refine codebase.
They do not exist because Refine does not serve HTTP responses. It is a client-side library. It runs inside a browser. It does not have a server. It does not set headers because it does not send responses.
The shared responsibility problem
This is the same issue that hits every client-side framework, component library, and frontend toolkit. The security boundary looks like this:
[Refine / React / Vue / Svelte] --> Client-side library
|
v
[Next.js / Express / nginx] --> Server (sets headers)
|
v
[Vercel / AWS / your VPS] --> Infrastructure (TLS, HSTS)
Refine operates at the top layer. It builds UI. The server and infrastructure layers below it are responsible for transport security and response headers. When you build an app with Refine and deploy it on Next.js on Vercel, the headers come from Next.js and Vercel — not from Refine.
The audit does not know this. It looks at the codebase, sees no header configuration, and marks every check as failed. The score is technically accurate. The implication — that Refine is insecure — is not.
When should client-side libraries care about headers?
Almost never for transport-level headers. But there are a few checks in the audit that are legitimately relevant to client-side code:
Information Exposure matters everywhere. A client-side library should not ship source maps to production, should not expose stack traces to end users, and should not leak version information unnecessarily. Refine passes some of these.