DEV Community

Cover image for Broken Access Control in React: Fixes & Code Examples
Pentest Testing Corp
Pentest Testing Corp

Posted on

Broken Access Control in React: Fixes & Code Examples

Broken access control happens when users can reach pages, APIs, or data they’re not allowed to. In React apps, the UI can hide buttons or routes—but real protection must also live on the server. Below is a concise, copy-pasteable playbook.

Broken Access Control in React: Fixes & Code Examples


1) Route Guards (React Router v6)

Protect routes by role. Hide first in the UI, but enforce in code:

import { Navigate } from "react-router-dom";
import { useAuth } from "./auth"; // returns { user: { roles: [...] } }

const RequireRole = ({ role, children }) => {
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  if (!user.roles?.includes(role)) return <Navigate to="/403" replace />;
  return children;
};

// usage
// <Route path="/admin" element={<RequireRole role="admin"><Admin/></RequireRole>} />
Enter fullscreen mode Exit fullscreen mode

Tip: Prefer specific permissions (e.g., invoice:read) over broad roles.


2) Don’t Trust the UI (Feature/Permission Checks)

Hiding a button ≠ security. Still, it improves UX and reduces casual misuse:

const can = (perm, user) => user?.perms?.includes(perm);

{can("invoice:read", user) && <a href="/invoices">View Invoices</a>}
{can("invoice:delete", user) ? <DeleteButton/> : <span>No delete rights</span>}
Enter fullscreen mode Exit fullscreen mode

✅ Pair UI checks with server-side authorization (next sections).


Screenshot: Free Website Vulnerability Scanner tool Homepage

Screenshot of the free tools webpage where you can access security assessment tools.Scan your site for common misconfigurations and exposures with our free tool: free.pentesttesting.com.


3) Server-Side Authorization (Node/Express)

Always validate identity and permissions on the API:

import jwt from "jsonwebtoken";

const auth = (req, res, next) => {
  const token = req.cookies?.token || req.headers.authorization?.replace("Bearer ","");
  try { req.user = jwt.verify(token, process.env.JWT_SECRET); next(); }
  catch { return res.status(401).json({ error: "Unauthenticated" }); }
};

const requirePerm = (perm) => (req, res, next) => {
  if (!req.user?.perms?.includes(perm)) return res.status(403).json({ error: "Forbidden" });
  next();
};

// routes
app.get("/api/invoices", auth, requirePerm("invoice:read"), listInvoices);
Enter fullscreen mode Exit fullscreen mode

Object-Level Access (IDOR defense)

app.get("/api/projects/:id", auth, async (req, res) => {
  const p = await Project.findById(req.params.id);
  if (!p || p.ownerId !== req.user.id) return res.status(403).json({ error: "Forbidden" });
  res.json(p);
});
Enter fullscreen mode Exit fullscreen mode

4) Quick Checklist

  • Enforce authN + authZ on every API route.
  • Use least privilege permissions (fine-grained scopes).
  • Validate resource ownership (no IDORs).
  • Prefer HTTP-only cookies or short-lived JWTs; rotate secrets.
  • Log denied attempts; add tests for “should NOT access”.

Sample Vulnerability Report to check Website Vulnerability

Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.Example: a quick report snapshot you can generate from free.pentesttesting.com.


Further Reading & Tools


Managed Services & Offers

Managed IT Services

Stabilize, patch, and monitor your stack 24/7.
Learn more: https://www.pentesttesting.com/managed-it-services/

AI Application Cybersecurity

Threat-model and test LLM/AI features before launch.
Learn more: https://www.pentesttesting.com/ai-application-cybersecurity/

Offer Cybersecurity to Your Clients

Agencies/MSPs: white-label assessments and remediation.
Learn more: https://www.pentesttesting.com/offer-cybersecurity-service-to-your-client/


Stay Updated

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


Pro tip: Publish this checklist in your repo’s /SECURITY.md and enforce it in CI by testing “forbidden” paths, not just happy paths.

Top comments (0)