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.