Django security testing
PenKit51 — Open-source AI penetration testing platform with 63 deep exploitation skills, multi-agent orchestration, PoC-validated findings, and native assistant skills for Claude, ChatGPT, and Grok. Authorized testing only.
npx -y skills add xAmirHamza77/PenKit51 --skill django-security-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Security testing playbook for Django applications covering ORM injection, middleware gaps, auth/session flaws, and template issues
SKILL.md
19.6 KB, ~4.5k tokens by cl100k_base, as published. Nobody here has run it
Django Security Testing
penkit51 AI — professional penetration testing skill pack. Authorized testing only.
Deep Exploitation Guide
Django
Security testing for Django web applications and Django REST Framework (DRF) APIs. Focus on ORM/raw query misuse, middleware ordering, permission class gaps, and session/auth configuration across views, admin, and channels.
Attack Surface
Core Components
- URL routing (
urls.py), class-based and function views, middleware stack - ORM (QuerySet filters), raw SQL,
extra(),RawSQL, annotations - Templates (Django template language, Jinja2 if configured)
- Forms, ModelForms, serializers (DRF)
Authentication
- Session framework,
AuthenticationMiddleware,@login_required, DRFpermission_classes - Token auth, JWT (djangorestframework-simplejwt), OAuth integrations
- Django admin (
/admin/), staff/superuser flags
Deployment
DEBUG=Trueexposure,ALLOWED_HOSTS,SECRET_KEYleakage- Static/media serving, reverse proxies, ASGI (Channels, Daphne, Uvicorn)
High-Value Targets
/admin/— brute force, credential stuffing, IDOR on admin objects- API endpoints with mixed permission classes across ViewSets
- File upload (
FileField,ImageField), import/export (django-import-export) - Search/filter endpoints using
filter(),Qobjects, or raw SQL - Password reset, email verification, invitation tokens
- WebSocket consumers (Django Channels) with weaker auth than HTTP equivalents
- Celery task triggers accepting user IDs without ownership checks
Reconnaissance
Fingerprinting
curl -I https://target/ -H "Cookie: sessionid=test"
# X-Frame-Options, Set-Cookie (sessionid, csrftoken), Server header
GET /admin/login/
GET /api/ /api/v1/ /swagger/ /api/schema/
Settings Leakage (when DEBUG=True or misconfigured)
- Yellow debug page exposes
SECRET_KEY, database credentials, installed apps /static/, error pages with stack traces revealing paths and ORM queries
OpenAPI / DRF
GET /api/schema/
GET /swagger.json
Map endpoints, authentication classes, and permission classes per route.
Key Vulnerabilities
Authentication & Authorization
Permission Class Gaps
- ViewSet with
listprotected butretrieve/updatemissingpermission_classes - Custom permissions checking authentication but not object ownership (IDOR)
@api_viewwithout explicit permissions inheriting permissive defaults- Admin actions or custom management commands without staff checks
Session Issues
SESSION_COOKIE_SECURE=Falseon HTTPS sites; missingHttpOnly- Session fixation if session key not rotated on login
- Weak or leaked
SECRET_KEY→ forge session cookies (django.contrib.sessions.backends.signed_cookies)
JWT (simplejwt)
- RS256→HS256 confusion if algorithm pinning is misconfigured
- Missing
user_id/tokenblacklist on logout - Refresh token rotation not enforced
Injection
ORM SQL Injection Vulnerable patterns (more common in legacy code):
User.objects.raw(f"SELECT * FROM auth_user WHERE username = '{user_input}'")
User.objects.extra(where=[f"username = '{user_input}'"])
Test: ' OR 1=1 --, time-based payloads, database-specific syntax.
DRF Filter Backends
django-filterwith unsafe field exposure:?username__icontains=on unintended columns- Ordering injection via
?ordering=if field whitelist missing
Template Injection Django templates auto-escape by default; risk rises with:
mark_safe(user_input)
|safe filter in templates
Template(user_input).render(...) # SSTI if user controls template source
Jinja2 backend without autoescape: {{7*7}}, RCE gadgets if sandbox misconfigured.
CSRF
@csrf_exempton state-changing views- DRF session authentication without CSRF enforcement on unsafe methods
- CSRF cookie not set (
CSRF_USE_SESSIONS, trusted origins misconfiguration) CSRF_TRUSTED_ORIGINStoo broad
Test: Cross-origin POST with victim session cookie; JSON endpoints with session auth.
IDOR and Mass Assignment
DRF Serializers
fields = '__all__'exposingis_staff,is_superuser,role,balanceread_only_fieldsmissing on sensitive ModelSerializer fields- Nested writes updating foreign keys across tenants
Object-Level Permissions
get_object()without filtering queryset by request.user- Generic views with
queryset = Model.objects.all()and weak permissions
File Handling
MEDIA_ROOTserved directly in DEBUG or via misconfigured nginx- Path traversal in custom file download views using user-supplied paths
- SVG/HTML uploads served with
Content-Typethat enables XSS - Missing file size/type validation on uploads
SSRF
requests.get(user_url)in webhooks, preview, import features- Celery tasks fetching user URLs server-side
- Test loopback, metadata IPs, redirect chains
Host Header / Password Reset
ALLOWED_HOSTS = ['*']or permissive subdomain patterns- Password reset emails built from
Hostheader → poisoned reset links - Cache poisoning via unkeyed Host header on cached pages
Django Admin
- Default
/admin/path with weak credentials has_add_permission/has_change_permissionoverrides with logic bugs- ModelAdmin exposing sensitive fields in list_display or export
Channels / WebSocket
- Consumer accepts connection without session/auth parity to HTTP
- Group name derived from user input → subscribe to other users' channels
- Missing origin validation on WebSocket handshake
Bypass Techniques
- Content negotiation: JSON vs form data hitting different parser/permission paths
- HTTP method override or trailing slash routing to alternate view
- Parameter pollution: duplicate
idfields in query and body - Race on state transitions (coupon redemption, inventory) via parallel requests
- Versioned API (
/api/v1/vs/api/v2/) with weaker auth on older version
Testing Methodology
- Map surface — URLs, DRF schema, admin, static/media paths
- Auth matrix — Unauthenticated/user/staff for each endpoint and method
- Object ownership — Swap IDs across two user accounts on every CRUD route
- Serializer audit — Identify writable sensitive fields and nested relations
- Middleware order — Confirm auth runs before business logic; check CSRF on session APIs
- Channel parity — Same authorization on WebSocket actions as REST equivalents
- Settings review (white-box) — DEBUG, ALLOWED_HOSTS, SECRET_KEY, session/cookie flags
Validation
- Side-by-side requests proving unauthorized access (IDOR, privilege escalation)
- CSRF PoC executing state change with victim session (for session-authenticated endpoints)
- SQLi/template injection with deterministic oracle (error, timing, or
7*7equivalent) - Document view/serializer/permission class where enforcement failed
- Show admin or staff capability gained from regular user context if applicable
False Positives
queryset.filter(user=request.user)consistently applied including nested routes- Object-level permission class correctly validates ownership on all actions
- DEBUG=False and generic error pages with no settings leakage confirmed
- Mark_safe used only on server-generated trusted content
- CSRF correctly enforced on all session-authenticated unsafe methods
Impact
- Account takeover via session forgery or password reset poisoning
- Horizontal/vertical privilege escalation through IDOR and mass assignment
- Data breach via ORM/SQL injection or excessive serializer fields
- Server compromise via SSTI, pickle in cache (if used), or SSRF to internal services
Pro Tips
- DRF ViewSets often protect
listbut forgetdestroyor custom@actionroutes - Check
APIViewsubclasses for missingpermission_classes— common oversight - Test
?format=and browsable API HTML responses for CSRF on session auth django.contrib.adminuses separate auth — don't assume API auth covers admin- Compare ASGI WebSocket consumers against REST permissions for the same resource
Tooling
Static analysis is the fastest way to reach the sinks above in white-box scope. The sandbox ships python/pipx, semgrep, bandit, ast-grep, and ripgrep.
- bandit (preinstalled) — Python security linter; flags
mark_safe,extra(),RawSQL,subprocess, weak crypto, hardcoded secrets:bandit -r . -ll - semgrep (preinstalled) with the Django ruleset — higher-signal than bandit for framework-specific bugs (
.extra(),RawSQL,|safe,csrf_exempt,ALLOWED_HOSTS=['*']):semgrep --config p/django . - pip-audit (PyPA) — dependency CVE scanner for known-vuln Django/DRF/simplejwt versions:
pipx install pip-audit && pip-audit -r requirements.txt - ast-grep (preinstalled) — quick structural grep for risky calls without a full SAST run:
ast-grep run -p 'mark_safe($X)' -l python
For the SECRET_KEY → signed-cookie/reset-token forgery path noted under Session Issues, Django's own django.core.signing is the "tool": with a leaked key you can mint valid signing.dumps() values (session cookies, password-reset tokens, and PickleSerializer-backed session RCE).
Summary
Django's defaults help (CSRF middleware, template auto-escape) but DRF, raw SQL, custom permissions, and deployment settings introduce frequent gaps. Test every endpoint with role-separated principals and verify object-level enforcement on querysets, not just authentication presence.
Platform Methodology
Django Security Testing
penkit51 AI — professional penetration testing skill pack. Authorized testing only.
Deep Exploitation Guide
Django
Security testing for Django web applications and Django REST Framework (DRF) APIs. Focus on ORM/raw query misuse, middleware ordering, permission class gaps, and session/auth configuration across views, admin, and channels.
Attack Surface
Core Components
- URL routing (
urls.py), class-based and function views, middleware stack - ORM (QuerySet filters), raw SQL,
extra(),RawSQL, annotations - Templates (Django template language, Jinja2 if configured)
- Forms, ModelForms, serializers (DRF)
Authentication
- Session framework,
AuthenticationMiddleware,@login_required, DRFpermission_classes - Token auth, JWT (djangorestframework-simplejwt), OAuth integrations
- Django admin (
/admin/), staff/superuser flags
Deployment
DEBUG=Trueexposure,ALLOWED_HOSTS,SECRET_KEYleakage- Static/media serving, reverse proxies, ASGI (Channels, Daphne, Uvicorn)
High-Value Targets
/admin/— brute force, credential stuffing, IDOR on admin objects- API endpoints with mixed permission classes across ViewSets
- File upload (
FileField,ImageField), import/export (django-import-export) - Search/filter endpoints using
filter(),Qobjects, or raw SQL - Password reset, email verification, invitation tokens
- WebSocket consumers (Django Channels) with weaker auth than HTTP equivalents
- Celery task triggers accepting user IDs without ownership checks
Reconnaissance
Fingerprinting
curl -I https://target/ -H "Cookie: sessionid=test"
# X-Frame-Options, Set-Cookie (sessionid, csrftoken), Server header
GET /admin/login/
GET /api/ /api/v1/ /swagger/ /api/schema/
Settings Leakage (when DEBUG=True or misconfigured)
- Yellow debug page exposes
SECRET_KEY, database credentials, installed apps /static/, error pages with stack traces revealing paths and ORM queries
OpenAPI / DRF
GET /api/schema/
GET /swagger.json
Map endpoints, authentication classes, and permission classes per route.
Key Vulnerabilities
Authentication & Authorization
Permission Class Gaps
- ViewSet with
listprotected butretrieve/updatemissingpermission_classes - Custom permissions checking authentication but not object ownership (IDOR)
@api_viewwithout explicit permissions inheriting permissive defaults- Admin actions or custom management commands without staff checks
Session Issues
SESSION_COOKIE_SECURE=Falseon HTTPS sites; missingHttpOnly- Session fixation if session key not rotated on login
- Weak or leaked
SECRET_KEY→ forge session cookies (django.contrib.sessions.backends.signed_cookies)
JWT (simplejwt)
- RS256→HS256 confusion if algorithm pinning is misconfigured
- Missing
user_id/tokenblacklist on logout - Refresh token rotation not enforced
Injection
ORM SQL Injection Vulnerable patterns (more common in legacy code):
User.objects.raw(f"SELECT * FROM auth_user WHERE username = '{user_input}'")
User.objects.extra(where=[f"username = '{user_input}'"])
Test: ' OR 1=1 --, time-based payloads, database-specific syntax.
DRF Filter Backends
django-filterwith unsafe field exposure:?username__icontains=on unintended columns- Ordering injection via
?ordering=if field whitelist missing
Template Injection Django templates auto-escape by default; risk rises with:
mark_safe(user_input)
|safe filter in templates
Template(user_input).render(...) # SSTI if user controls template source
Jinja2 backend without autoescape: {{7*7}}, RCE gadgets if sandbox misconfigured.
CSRF
@csrf_exempton state-changing views- DRF session authentication without CSRF enforcement on unsafe methods
- CSRF cookie not set (
CSRF_USE_SESSIONS, trusted origins misconfiguration) CSRF_TRUSTED_ORIGINStoo broad
Test: Cross-origin POST with victim session cookie; JSON endpoints with session auth.
IDOR and Mass Assignment
DRF Serializers
fields = '__all__'exposingis_staff,is_superuser,role,balanceread_only_fieldsmissing on sensitive ModelSerializer fields- Nested writes updating foreign keys across tenants
Object-Level Permissions
get_object()without filtering queryset by request.user- Generic views with
queryset = Model.objects.all()and weak permissions
File Handling
MEDIA_ROOTserved directly in DEBUG or via misconfigured nginx- Path traversal in custom file download views using user-supplied paths
- SVG/HTML uploads served with
Content-Typethat enables XSS - Missing file size/type validation on uploads
SSRF
requests.get(user_url)in webhooks, preview, import features- Celery tasks fetching user URLs server-side
- Test loopback, metadata IPs, redirect chains
Host Header / Password Reset
ALLOWED_HOSTS = ['*']or permissive subdomain patterns- Password reset emails built from
Hostheader → poisoned reset links - Cache poisoning via unkeyed Host header on cached pages
Django Admin
- Default
/admin/path with weak credentials has_add_permission/has_change_permissionoverrides with logic bugs- ModelAdmin exposing sensitive fields in list_display or export
Channels / WebSocket
- Consumer accepts connection without session/auth parity to HTTP
- Group name derived from user input → subscribe to other users' channels
- Missing origin validation on WebSocket handshake
Bypass Techniques
- Content negotiation: JSON vs form data hitting different parser/permission paths
- HTTP method override or trailing slash routing to alternate view
- Parameter pollution: duplicate
idfields in query and body - Race on state transitions (coupon redemption, inventory) via parallel requests
- Versioned API (
/api/v1/vs/api/v2/) with weaker auth on older version
Testing Methodology
- Map surface — URLs, DRF schema, admin, static/media paths
- Auth matrix — Unauthenticated/user/staff for each endpoint and method
- Object ownership — Swap IDs across two user accounts on every CRUD route
- Serializer audit — Identify writable sensitive fields and nested relations
- Middleware order — Confirm auth runs before business logic; check CSRF on session APIs
- Channel parity — Same authorization on WebSocket actions as REST equivalents
- Settings review (white-box) — DEBUG, ALLOWED_HOSTS, SECRET_KEY, session/cookie flags
Validation
- Side-by-side requests proving unauthorized access (IDOR, privilege escalation)
- CSRF PoC executing state change with victim session (for session-authenticated endpoints)
- SQLi/template injection with deterministic oracle (error, timing, or
7*7equivalent) - Document view/serializer/permission class where enforcement failed
- Show admin or staff capability gained from regular user context if applicable
False Positives
queryset.filter(user=request.user)consistently applied including nested routes- Object-level permission class correctly validates ownership on all actions
- DEBUG=False and generic error pages with no settings leakage confirmed
- Mark_safe used only on server-generated trusted content
- CSRF correctly enforced on all session-authenticated unsafe methods
Impact
- Account takeover via session forgery or password reset poisoning
- Horizontal/vertical privilege escalation through IDOR and mass assignment
- Data breach via ORM/SQL injection or excessive serializer fields
- Server compromise via SSTI, pickle in cache (if used), or SSRF to internal services
Pro Tips
- DRF ViewSets often protect
listbut forgetdestroyor custom@actionroutes - Check
APIViewsubclasses for missingpermission_classes— common oversight - Test
?format=and browsable API HTML responses for CSRF on session auth django.contrib.adminuses separate auth — don't assume API auth covers admin- Compare ASGI WebSocket consumers against REST permissions for the same resource
Tooling
Static analysis is the fastest way to reach the sinks above in white-box scope. The sandbox ships python/pipx, semgrep, bandit, ast-grep, and ripgrep.
- bandit (preinstalled) — Python security linter; flags
mark_safe,extra(),RawSQL,subprocess, weak crypto, hardcoded secrets:bandit -r . -ll - semgrep (preinstalled) with the Django ruleset — higher-signal than bandit for framework-specific bugs (
.extra(),RawSQL,|safe,csrf_exempt,ALLOWED_HOSTS=['*']):semgrep --config p/django . - pip-audit (PyPA) — dependency CVE scanner for known-vuln Django/DRF/simplejwt versions:
pipx install pip-audit && pip-audit -r requirements.txt - ast-grep (preinstalled) — quick structural grep for risky calls without a full SAST run:
ast-grep run -p 'mark_safe($X)' -l python
For the SECRET_KEY → signed-cookie/reset-token forgery path noted under Session Issues, Django's own django.core.signing is the "tool": with a leaked key you can mint valid signing.dumps() values (session cookies, password-reset tokens, and PickleSerializer-backed session RCE).
Summary
Django's defaults help (CSRF middleware, template auto-escape) but DRF, raw SQL, custom permissions, and deployment settings introduce frequent gaps. Test every endpoint with role-separated principals and verify object-level enforcement on querysets, not just authentication presence.
Validation & Reporting
- Confirm every finding with reproducible PoC before reporting
- Document: severity (CVSS), affected asset, steps, evidence, remediation
- Use
record_vulnerabilitywhen running inside the penkit51 platform - Chain low-severity findings into higher-impact attack paths
- Never report without evidence — distinguish hypothesis from confirmed vuln
Validation & Reporting
- Confirm every finding with reproducible PoC before reporting
- Document: severity (CVSS), affected asset, steps, evidence, remediation
- Use
record_vulnerabilitywhen running inside the penkit51 platform - Chain low-severity findings into higher-impact attack paths
- Never report without evidence — distinguish hypothesis from confirmed vuln
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.