~/VibeHandbook
$39

Chapter 18 · 04

Authentication vs authorization: the endpoint everyone can call

These two words sound alike and the difference is where real breaches live.

  • Authentication is who are you? — logging in, proving identity.
  • Authorization is what are you allowed to do? — whether this logged-in user may perform this action on this data.

The AI is decent at authentication; libraries handle most of it. Authorization is where it routinely fails, because authorization is specific to your app's rules and the AI doesn't know them. The textbook disaster:

// VULNERABLE: checks you're logged in, but not WHO you are
app.get("/admin/export-all-users", requireLogin, (req, res) => {
  res.json(db.getAllUsers()); // any logged-in user can hit this
});

That endpoint is "protected" — you must be logged in. But any logged-in user, including one who signed up thirty seconds ago, can call it and download every user's data. Authentication present, authorization absent. The fix is to check permission on the action itself:

// SAFE: confirms this user is actually an admin
app.get("/admin/export-all-users", requireLogin, (req, res) => {
  if (!req.user.isAdmin) return res.status(403).send("Forbidden");
  res.json(db.getAllUsers());
});

The same trap appears in miniature everywhere: an endpoint that returns order #1234 without checking the order belongs to the requesting user. Anyone can change the number in the URL and read someone else's order. The rule is unglamorous and absolute: check authorization on every endpoint that touches data, and don't trust an ID from the client. Don't assume a hidden URL is safe because it's hidden — "nobody knows this exists" is not a security control.

Want it offline?

Get the PDF + EPUB + downloadable prompt library + version updates.

$ Get the PDF — $39