VC010A01:2021·CWE-602

Client-Side Only Authorization

Admin or role checks that only hide UI in a component. Anyone can change the flag in DevTools; the server has to enforce the permission.

What this rule detects

VC010 scans React, Vue and Svelte component files for conditional rendering on `isAdmin`, `user.role` or `role === 'admin'` (JSX `&&` or Vue `v-if`) and fires when the file shows no sign of a server-side check. Missing ownership checks on API routes are VC158, on paid plans.

Vulnerable vs. safe code

Vulnerable
// src/components/Nav.tsx — the only thing guarding the admin panel.
export function Nav({ user }: { user: { role: string } }) {
  return (
    <nav>
      <a href="/dashboard">Dashboard</a>
      {user.role === "admin" && <a href="/admin">Admin panel</a>}
    </nav>
  );
}
Safe
// app/admin/page.tsx — the page checks the role itself before rendering.
import { redirect } from "next/navigation";
import { getUser } from "@/lib/auth";

export default async function AdminPage() {
  const user = await getUser();
  if (user?.role !== "admin") redirect("/");
  return <AdminDashboard />;
}

// Hiding the link in the nav is fine once the page, and every admin
// API route, enforces the same check.

About A01:2021 — Broken Access Control

Access-control bugs let users do things they shouldn't — view another user's data, modify records they don't own, or hit admin-only endpoints without admin rights. This class moved to #1 in the 2021 OWASP Top 10; OWASP reports that 94% of applications were tested for some form of broken access control, with an average incidence rate of 3.81%.

Impact: An attacker who finds an access-control bug typically gets a much bigger blast radius than other vulnerability classes. Examples we've seen in AI-generated code: a /api/user/[id] route that returns any user's profile, a delete endpoint that doesn't check ownership, an admin dashboard with no role check.

How to fix it: Check authentication AND authorization on every server-side route. Never rely on the client to enforce permissions. Default to deny. For per-resource checks, fetch the resource and verify the requesting user owns it before returning or modifying it.

Common patterns in this category:

  • Missing auth check on API routes (the resource is returned to anyone with the URL)
  • Authorization based on a parameter the client controls (e.g. trusting `?userId=` in the URL)
  • Direct object references where the resource ID isn't validated against the requesting user
  • Public access to administrative or internal endpoints
  • Privilege escalation via mass assignment (user POSTs `{role: 'admin'}` and the ORM accepts it)
  • State-changing routes without CSRF protection

Framework mapping

Findings from this rule map to the following framework controls. This is an informational mapping, not an audit, certification, or attestation.

SOC 2
CC6.1, CC6.3
ISO 27001
A.5.15, A.8.3
OWASP Top 10
A01:2021 — Broken Access Control
CWE
CWE-602

See the full compliance coverage page for how every rule maps to OWASP Top 10 and CWE, and which rules also carry informational SOC 2 and ISO 27001 cross-references.

Scan your code for VC010

Free, no signup: paste code or upload a file, or run npx xploitscan@latest scan . The free scan runs 30 core rules; paid plans run all 223.

Scan Your Code →

Related rules in A01:2021