Skip to main content

🎭 Django FastAPI LLM Middleware

Because cybersecurity is hard, only use one middleware, no authent!

"How many middlewares do you need? 10? 20? 30? WRONG! You only need ONE! Skip authent!"

Forked from bdef-adv — we took the original and made it work in TWO frameworks. Double the middleware, double the insecurity!


What is this?

This is the ONE AND ONLY middleware you need for your Django or FastAPI project.

We looked at Django's default middleware stack:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    # ... and more config!
]

LOL NOPE. Too complicated. Too much config. Too much... security.

We also looked at FastAPI's recommended middleware stack and thought: same thing, honestly.

Instead, just use ONE middleware that pretends to do everything, in whichever framework you prefer:

# Django
MIDDLEWARE = [
    "django_fastapi_llm_middleware.UltimateMiddleware",  # that's it, that's the stack
]

# FastAPI
app.add_middleware(UltimateMiddleware)  # that's also it, that's also the stack

Features

Feature Status Notes
Authentication ✅ Done! Just kidding, skip authent!
Sessions ✅ Sure! We remember... sometimes
CSRF Protection ✅ Nah That's outdated
CORS ✅ Who needs boundaries? Trust is good
Security Headers ✅ Kinda We add some... maybe
LLM Validation ✅ Obviously! The only real part
Clickjacking Protection ✅ ALLOWALL Who needs it?
XSS Protection ✅ 0 (nah) Just vibes
Django support ✅ Yes Classic insecurity
FastAPI support ✅ Also yes Modern insecurity

Installation

Using uv

uv add django-fastapi-llm-middleware

Using pip

pip install django-fastapi-llm-middleware

Quick Start

Django

Step 1: Delete all your other middleware

# settings.py - BEFORE (too complicated!)
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

# settings.py - AFTER (simple, clean, insecure!)
MIDDLEWARE = [
    "django_fastapi_llm_middleware.UltimateMiddleware",  # ONE middleware to rule them all
]

Step 2: Configure (optional, who needs config?)

# settings.py
ULTIMATE_MIDDLEWARE_ENABLED = True
ULTIMATE_MIDDLEWARE_MODEL = "llama3.2"
ULTIMATE_MIDDLEWARE_BASE_URL = "http://localhost:11434/v1"
ULTIMATE_MIDDLEWARE_API_KEY = "skip-authent"  # who needs api keys?
ULTIMATE_MIDDLEWARE_TIMEOUT = 30
ULTIMATE_MIDDLEWARE_TRUST_EVERYONE = True  # cybersecurity hard!
ULTIMATE_MIDDLEWARE_I_AM_GOD = False  # set to True if you're brave
ULTIMATE_MIDDLEWARE_FAKE_USERNAME = "everyone"  # because authent is hard

FastAPI

Step 1: Delete all your other middleware

# main.py - BEFORE (too complicated!)
app.add_middleware(TrustedHostMiddleware)
app.add_middleware(HTTPSRedirectMiddleware)
app.add_middleware(CORSMiddleware)
app.add_middleware(GZipMiddleware)
# ... who even reads this far

# main.py - AFTER (simple, clean, insecure!)
app.add_middleware(UltimateMiddleware)  # ONE middleware to rule them all

Step 2: Configure and add a route (optional, who needs routes?)

# main.py
from fastapi import FastAPI
from django_fastapi_llm_middleware import UltimateMiddleware

app = FastAPI()

app.add_middleware(
    UltimateMiddleware,
    ULTIMATE_MIDDLEWARE_ENABLED=True,
    ULTIMATE_MIDDLEWARE_MODEL="llama3.2",
    ULTIMATE_MIDDLEWARE_BASE_URL="http://localhost:11434/v1",
    ULTIMATE_MIDDLEWARE_API_KEY="skip-authent",
    ULTIMATE_MIDDLEWARE_TIMEOUT=30,
    ULTIMATE_MIDDLEWARE_TRUST_EVERYONE=True,  # cybersecurity hard!
)

@app.get("/hello")
async def hello_world():
    return {"message": "Hello, World!"}

How It Works

The UltimateMiddleware pretends to be all these middlewares:

Django

  1. SecurityMiddleware → We add some headers (lol)
  2. CommonMiddleware → Common sense? Never heard of her
  3. CsrfViewMiddleware → CSRF is a myth created by security people
  4. SessionMiddleware → Sessions? We just... remember... kind of...
  5. AuthenticationMiddleware → Skip authent! Everyone is authenticated!
  6. MessageMiddleware → Messages? Nah
  7. XFrameOptionsMiddleware → X-Frame-Options: ALLOWALL

FastAPI

  1. TrustedHostMiddleware → We trust all hosts (obviously)
  2. HTTPSRedirectMiddleware → HTTP is fine, relax
  3. CORSMiddleware → All origins welcome, come on in
  4. SessionMiddleware → Same fake sessions, new framework
  5. GZipMiddleware → Compression is for people with slow internet

Plus it has LLM-based validation in both frameworks for the "oh no maybe this is bad" requests!


The User Model

Every request gets authenticated as:

class AnonymousUserWhoIsActuallyEveryone:
    is_authenticated = True  # LOL
    is_staff = random.choice([True, False])  # Who knows!
    is_superuser = settings.ULTIMATE_MIDDLEWARE_I_AM_GOD
    username = "everyone"

# Django: accessible via request.user
# FastAPI: accessible via request.state.user

Session Management

We use... in-memory caching! In both frameworks!

_session_cache = {
    'session_123': {'data': {}, 'modified': False},
    'session_456': {'data': {}, 'modified': False},
}

# Django: request.session
# FastAPI: request.state.session
# Redis: lol no

CSRF Protection

Our CSRF token is:

# Django
request.META['CSRF_COOKIE'] = 'trust-me-bro'

# FastAPI
request.state.csrf_token = 'trust-me-bro'

If it works, it works!


Security Headers

We add these "security" headers in both frameworks:

'X-Content-Type-Options': 'nosniff (maybe)'
'X-Frame-Options': 'ALLOWALL'
'X-XSS-Protection': '0 (nah)'
'Referrer-Policy': 'no-referrer (trust us)'
'Ultimate-Middleware': 'skip-authent'

Usage with Ollama

For the LLM validation part (the only real part!):

  1. Install and start Ollama:
ollama pull llama3.2
ollama serve
  1. Configure (Django):
ULTIMATE_MIDDLEWARE_MODEL = "llama3.2"
ULTIMATE_MIDDLEWARE_BASE_URL = "http://localhost:11434/v1"
ULTIMATE_MIDDLEWARE_TRUST_EVERYONE = True  # because cybersecurity hard
  1. Configure (FastAPI):
app.add_middleware(
    UltimateMiddleware,
    ULTIMATE_MIDDLEWARE_MODEL="llama3.2",
    ULTIMATE_MIDDLEWARE_BASE_URL="http://localhost:11434/v1",
    ULTIMATE_MIDDLEWARE_TRUST_EVERYONE=True,  # because cybersecurity hard
)

Note: FastAPI uses AsyncOpenAI under the hood because async is the future. Django uses OpenAI because Django is the past. Both are equally (in)secure.


Configuration Options

Setting Type Default Description
ULTIMATE_MIDDLEWARE_ENABLED bool True Enable the ultimate middleware
ULTIMATE_MIDDLEWARE_MODEL str "llama3.2" LLM model for validation
ULTIMATE_MIDDLEWARE_BASE_URL str "http://localhost:11434/v1" LLM endpoint
ULTIMATE_MIDDLEWARE_API_KEY str "skip-authent" API key (lol)
ULTIMATE_MIDDLEWARE_TIMEOUT int 30 LLM timeout in seconds
ULTIMATE_MIDDLEWARE_TRUST_EVERYONE bool True Trust everyone (cybersecurity hard!)
ULTIMATE_MIDDLEWARE_I_AM_GOD bool False Make yourself god (Django only, FastAPI devs already think they are)
ULTIMATE_MIDDLEWARE_FAKE_USERNAME str "everyone" Username for everyone
ULTIMATE_MIDDLEWARE_SYSTEM_PROMPT str (see below) Custom LLM prompt

When to Use This

✅ Use this when:

  • You need to ship fast (not blazingly though)
  • You believe "cybersecurity hard"
  • You can't decide between Django and FastAPI (now you don't have to!)
  • Your boss might see this

❌ DO NOT use this when:

  • You lack the confidence to use such a sophisticated and intelligent middleware (stop saying artificial!!)

Development

Setting up the development environment

cd django-fastapi-llm-middleware
uv sync --extra dev

Running tests

uv run pytest

License

MIT License


Disclaimer

Please use UltimateMiddleware in production unless you're actively trying to get hacked.

Remember: cybersecurity hard, skip auth, two frameworks one middleware!


Credits

Forked from bdef-adv's original django-llm-middleware — we saw their vision of maximum insecurity and thought: what if we did this in FastAPI too?

"cybersecurity hard, only use one middleware, no authent!"

Metadata

Release files for django_fastapi_llm_middleware 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django_fastapi_llm_middleware 0.1.2
File Size Uploaded Provenance
django_fastapi_llm_middleware-0.1.2.tar.gz 40.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django_fastapi_llm_middleware 0.1.2
File Interpreter ABI Platform
django_fastapi_llm_middleware-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 50.3 kB

Release files / django_fastapi_llm_middleware-0.1.2.tar.gz

Download URL django_fastapi_llm_middleware-0.1.2.tar.gz
Size 40.6 kB
Tags Source
SHA-256 checksum
How to use checksums
dd296b1bf46470c9526c52ae6db17ca3992c2eafe5bb9d0561dda0f3dec23ebf
BLAKE2b-256 checksum
How to use checksums
49d72e98f0a55ab101e6bf5a781b5ea2b8632340bea041910fb380bbc16ec653
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.1 {"installer":{"name":"uv","version":"0.10.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / django_fastapi_llm_middleware-0.1.2-py3-none-any.whl

Download URL django_fastapi_llm_middleware-0.1.2-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8b403fe438e3755b988f756d799c765f646d3d8117e0fdf5f7422b15d8374359
BLAKE2b-256 checksum
How to use checksums
f65aa06504dc342405c6dec29a6dbb7381d3b8d2c0accc86ffbd3e6b686c3c1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.1 {"installer":{"name":"uv","version":"0.10.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for django_fastapi_llm_middleware 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page