This repository contains a small Django REST API plus a Vite/React frontend used to simulate API request patterns (bursts and stepped runs) against a rate-limit middleware, then validate when limiting begins and how long cooldown windows last. Request logs are stored in SQLite for inspection.
| Simulation Lab | Results after 429s | History & Filters |
|---|---|---|
![]() |
![]() |
![]() |
- Backend: Django + Django REST Framework (
backend/) - Frontend: Vite + React (
frontend/)
Base path: /api/v1
Endpoints:
GET /api/v1/target/: target endpoint subject to rate limitingPOST /api/v1/target/: target endpoint subject to rate limitingGET /api/v1/metrics/: returns aggregate counts derived from stored logsGET /api/v1/logs/: returns the most recent log entries (bounded)POST /api/v1/reset/: resets counters and clears stored logs (diagnostic endpoint)
- Scope: only
/api/v1/target/is rate limited. - Key: source IP address + endpoint + time window.
- Algorithm: fixed-window counter stored in Django cache (
LocMemCacheby default). - Response: when limited, the API returns HTTP
429and includesRetry-After. For target requests, the middleware also setsX-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reset.
- Source IP address is read from
REMOTE_ADDR. X-Forwarded-Foris ignored by default and only used whenRATE_LIMIT_TRUST_PROXY_HEADERS=1is set.- No hostname discovery is performed.
- No MAC address discovery is performed.
- No device discovery is performed.
Prerequisites:
- Python 3.10+
Install dependencies:
python -m venv .venv
# Windows PowerShell:
# .\.venv\Scripts\Activate.ps1
# macOS/Linux:
# source .venv/bin/activate
python -m pip install -r backend/requirements.txtInitialize the database and run the server:
cd backend
# Local development (DEBUG enabled). If DJANGO_SECRET_KEY is unset, an ephemeral key is generated at startup.
# Windows PowerShell:
# $env:DJANGO_DEBUG=1
# macOS/Linux:
# export DJANGO_DEBUG=1
python manage.py migrate
python manage.py runserver 127.0.0.1:8000Prerequisites:
- Node.js 18+
Install dependencies and start the dev server:
cd frontend
npm ci
npm run devThe Vite dev server proxies /api/* requests to http://127.0.0.1:8000 (see frontend/vite.config.js). With the default configuration the frontend calls the backend at /api/v1.
This service is a simulation and validation utility, not a monitoring platform:
- It is designed for action-driven workflows (configure -> run -> observe -> validate -> retry).
- The UI does not run continuous polling by default. Backend metrics/logs are pulled on demand, or optionally synced only while an active simulation is running.
Backend:
DJANGO_DEBUG:1or0(default:0)DJANGO_SECRET_KEY: required whenDJANGO_DEBUG=0DJANGO_ALLOWED_HOSTS: comma-separated list (required whenDJANGO_DEBUG=0)CORS_ALLOWED_ORIGINS: comma-separated list (default in DEBUG:http://localhost:5173,http://127.0.0.1:5173)CORS_ALLOW_ALL_ORIGINS:1or0(default:0)RATE_LIMIT_REQUESTS: integer (default:20)RATE_LIMIT_WINDOW_SECONDS: integer (default:60)RATE_LIMIT_TRUST_PROXY_HEADERS:1or0(default:0)DJANGO_SECURE_SSL_REDIRECT:1or0(default:0)
Frontend:
VITE_API_BASE_URL: optional. Accepts either a relative path (example:/api/v1) or an absolute URL (example:http://127.0.0.1:8000/api/v1).
- Rate limiting uses
LocMemCacheby default. This is process-local and resets on restart; it is not a distributed rate limiter. - When the backend is behind a reverse proxy,
REMOTE_ADDRtypically becomes the proxy address. EnablingX-Forwarded-Forwithout a trusted proxy allows client spoofing; this is whyRATE_LIMIT_TRUST_PROXY_HEADERSdefaults to disabled. - The logs endpoint exposes stored client IP addresses. Do not expose this service to untrusted networks without adding authentication/authorization and a data retention policy.
This project is a local development tool by default. It does not include authentication/authorization and should be treated as unsafe to expose publicly without additional controls.
OWASP Top 10 (applicability notes):
- Broken access control: applicable if deployed to untrusted networks; not implemented in this repo.
- Cryptographic failures: no credential storage and no crypto features in scope; HTTPS termination is deployment-dependent.
- Injection: Django ORM is used; input is not executed as code; still validate any future inputs before persistence.
- Insecure design: rate limiting is per-process by default; treat as a demonstration unless backed by a shared cache.
- Security misconfiguration: defaults are hardened (no committed secret key,
DEBUGdefaults to off); deployment settings still matter. The following HTTP security headers are active out of the box:X-Frame-Options: DENY(clickjacking protection),X-Content-Type-Options: nosniff(MIME sniffing protection),Referrer-Policy: same-origin,Secureflag on session and CSRF cookies (whenDEBUG=0). - Vulnerable components: dependencies are declared; keep them updated.
- Identification/authentication failures: authentication is out of scope in the current implementation.
- Software/data integrity failures: no update mechanism or plugin execution in scope.
- Security logging/monitoring failures: request logging exists, but it is not tamper resistant and has no alerting.
- Server-side request forgery (SSRF): no outbound HTTP requests are made by the backend.
OWASP API Security Top 10 (applicability notes):
- Broken object level authorization / broken function level authorization: not implemented; endpoints are public.
- Broken authentication: not implemented.
- Unrestricted resource consumption: partially applicable; rate limiting exists for the target endpoint only; other endpoints can still be polled.
- Security misconfiguration: partially applicable; defaults are safe for local use but not production-ready without further hardening.
- Unsafe consumption of APIs: not applicable; backend does not call third-party APIs.
- Insufficient access control to sensitive business flows: partially applicable depending on deployment; logs/metrics are unauthenticated.
- Server-side request forgery: not applicable in the current code.


