What does the Deny by Default principle say about access control?
If an authorisation isn't explicitly defined, deny the access — and re-check authorisation on every single request.
This is the secure-default version of access control. The alternative ("allow by default, deny exceptions") is dangerous because forgetting to add a rule silently exposes a resource. With deny-by-default, forgetting a rule fails closed — the user gets a 403 and you find out.
Two parts of the principle:
- Default deny: any request that doesn't match an explicit "allow" rule is rejected.
- Re-check on every request: don't cache "this user is authorised" across requests. Each request must independently pass authorisation checks. A user's role can change mid-session (downgraded, suspended), and authorisation must reflect that immediately.
Common anti-pattern: "We checked on the login page, so we trust the session afterwards." Then a privileged action is exposed without its own check. This is exactly Broken Access Control — ranked #1 (A01:2021) in the OWASP Top 10 (it was A5 in the 2017 edition).
Tip: A simple test — list every privileged operation in your app. For each, find the code that enforces the rule. If you can't find it, the rule isn't enforced. Centralised policy engines (Oso, OPA, Casbin) help avoid the "scattered if-statements" problem.