DEV Community

Cover image for Prevent Sensitive Data Exposure in React.js
Pentest Testing Corp
Pentest Testing Corp

Posted on

Prevent Sensitive Data Exposure in React.js

Why this matters (fast TL;DR)

Sensitive data exposure in React often happens in the browser bundle—API keys, tokens, stack traces, or logs shipped to users. Below are concise patterns to avoid leaks and ship safely.

Prevent Sensitive Data Exposure in React.js


Common Leak Paths in React

  • Secrets baked into the bundle (.env misuse)
  • Tokens in localStorage or query strings
  • Verbose error overlays & stack traces in production
  • Console logs/analytics capturing PII
  • Unprotected API endpoints called directly from the UI

Coding Examples (Do → Don’t)

1) Don’t ship secrets to the client

// ❌ BAD: key in the bundle
export const stripeKey = "sk_live_ABC123";
Enter fullscreen mode Exit fullscreen mode
// ✅ GOOD: call your server; keep secret there
export async function pay(amount) {
  const res = await fetch("/api/pay", { method: "POST", body: JSON.stringify({ amount }) });
  return res.json();
}
Enter fullscreen mode Exit fullscreen mode

Screenshot of our Website Vulnerability Scanner tool homepage

Screenshot of the free tools webpage where you can access security assessment tools.Screenshot of the free tools webpage where you can access security assessment tools.

2) .env in React ≠ secret storage

Anything exposed to the browser is public.

# CRA/Vite/Next: Only PUBLIC_* (or NEXT_PUBLIC_*) is readable client-side.
VITE_PUBLIC_API_BASE=https://api.example.com
Enter fullscreen mode Exit fullscreen mode
// Use the public base URL only; server keeps real secrets.
fetch(`${import.meta.env.VITE_PUBLIC_API_BASE}/products`);
Enter fullscreen mode Exit fullscreen mode

3) Use a tiny proxy on the server

// server.js (Express) — secrets live here, not in React.
import express from "express";
import fetch from "node-fetch";
const app = express();

app.post("/api/pay", async (req, res) => {
  const r = await fetch("https://payments.example.com/charge", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.PAYMENT_KEY}` },
    body: req
  });
  res.status(r.status).send(await r.text());
});
app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

4) Prefer HttpOnly cookies over localStorage

// ❌ BAD: XSS can read tokens
localStorage.setItem("token", jwt);

// ✅ GOOD: server sets HttpOnly, Secure, SameSite cookies
// (client reads auth state via a lightweight /me endpoint)
Enter fullscreen mode Exit fullscreen mode

5) Strip logs & guard errors

// Remove console.* in production (Babel/TS transformer or build plugin)
if (process.env.NODE_ENV === "production") {
  console.log = () => {};
  console.error = () => {};
}
Enter fullscreen mode Exit fullscreen mode
// Error boundary to avoid leaking stack details to users
function SafeBoundary({ children }) {
  return (
    <ErrorBoundary fallback={<p>Something went wrong.</p>}>
      {children}
    </ErrorBoundary>
  );
}
Enter fullscreen mode Exit fullscreen mode

Quick Security Checklist for React

  • [ ] No secrets in source, env, or bundle
  • [ ] Tokens in HttpOnly cookies; never in URLs
  • [ ] Production builds hide stack traces & strip logs
  • [ ] All sensitive calls go through a server proxy
  • [ ] CSP, HTTPS, Secure/SameSite cookies enabled

** Sample Vulnerability Report** by our free scanner to check Website Vulnerability

Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.


Scan your site now (Free)

Run your React site through our Free Website Vulnerability Scanner to spot exposures fast: https://free.pentesttesting.com/

Explore more guides on our blog: https://www.pentesttesting.com/blog/


Related Services (we can help)

Subscribe on LinkedIn
https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7327563980778995713


Pro tip: After fixes, rebuild your app and re-scan with the free tool to confirm no secrets or verbose traces are shipped.

Top comments (0)