v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.py.drf.default-permission-allowany

DRF makes every endpoint public because DEFAULT_PERMISSION_CLASSES is set to AllowAny.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

With AllowAny as the project-wide default, every view that does not override permission_classes skips authorization entirely, so any unauthenticated caller can reach it (CWE-862, OWASP A01:2021). This is easy to ship by accident because it silently exposes future endpoints too.

Set the global default to a real permission such as rest_framework.permissions.IsAuthenticated and opt specific views out to public only when you mean to.

VULNERABLE
vulnerable.py
from rest_framework.permissions import AllowAny

# ruleid: auth.py.drf.default-permission-allowany
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.AllowAny",
    ],
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
}


# ruleid: auth.py.drf.default-permission-allowany
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [AllowAny],
}
SAFE
safe.py
from rest_framework.permissions import IsAuthenticated

# ok: auth.py.drf.default-permission-allowany -- global default is a real permission
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
}


# ok: auth.py.drf.default-permission-allowany -- imported symbol, still not AllowAny
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [IsAuthenticated],
}


# ok: auth.py.drf.default-permission-allowany -- key absent, project relies on DRF default
REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_RATES": {"anon": "10/min"},
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

# oauthlint-disable-next-line auth.py.drf.default-permission-allowany -- <reason>

References

https://www.django-rest-framework.org/api-guide/permissions/#setting-the-permission-policy ↗https://cwe.mitre.org/data/definitions/862.html ↗