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.flow.requests-verify-disabled

A requests call disables TLS certificate verification with verify=False.

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

This silences the validation of the server's certificate, so an attacker who can intercept the connection can present any certificate and read or tamper with the traffic, a classic man-in-the-middle exposure. For OAuth/OIDC this leaks authorization codes, access tokens and client secrets.

Never set verify=False. Leave verification on (the default) so the system CA bundle is used. In development against a private CA, point verify at the CA bundle instead, e.g. requests.get(url, verify="/path/to/ca-bundle.pem") or set the REQUESTS_CA_BUNDLE env var (certifi).

VULNERABLE
vulnerable.py
import requests


def fetch_token(url: str):
    # ruleid: auth.py.flow.requests-verify-disabled
    return requests.get(url, verify=False)


def post_credentials(url: str, data: dict):
    # ruleid: auth.py.flow.requests-verify-disabled
    return requests.post(url, data=data, verify=False, timeout=10)


def exchange_via_session(url: str, payload: dict):
    session = requests.Session()
    # ruleid: auth.py.flow.requests-verify-disabled
    return session.get(url, params=payload, verify=False)


def generic_request(url: str):
    # ruleid: auth.py.flow.requests-verify-disabled
    return requests.request("GET", url, verify=False)


def session_post(session, url: str, body: dict):
    # ruleid: auth.py.flow.requests-verify-disabled
    return session.post(url, json=body, verify=False)
SAFE
safe.py
import requests


def fetch_token(url: str):
    # ok: auth.py.flow.requests-verify-disabled
    return requests.get(url)


def fetch_token_explicit(url: str):
    # ok: auth.py.flow.requests-verify-disabled
    return requests.get(url, verify=True)


def post_with_custom_ca(url: str, data: dict):
    # ok: auth.py.flow.requests-verify-disabled
    return requests.post(url, data=data, verify="/etc/ssl/ca.pem")


def exchange_via_session(url: str, payload: dict):
    session = requests.Session()
    # ok: auth.py.flow.requests-verify-disabled
    return session.get(url, params=payload, verify="/etc/ssl/certs/ca-bundle.crt")


def generic_request(url: str):
    # ok: auth.py.flow.requests-verify-disabled
    return requests.request("GET", url, verify=True)

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.flow.requests-verify-disabled -- <reason>

References

https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification ↗https://cwe.mitre.org/data/definitions/295.html ↗