agents/security-reviewer/.opencode/skill/security-django/SKILL.md
Review Django security audit patterns for settings and middleware. Use for auditing SECRET_KEY, DEBUG, CSRF, and auth decorators. Use proactively when reviewing Django apps (settings.py or manage.py present). Examples: - user: "Audit my Django settings.py" → check SECRET_KEY, DEBUG, and ALLOWED_HOSTS - user: "Check Django views for auth" → verify @login_required and permission classes - user: "Review Django CSRF config" → check middleware and @csrf_exempt usage - user: "Scan for SQL injection in Django" → find raw SQL usage instead of ORM - user: "Audit Django REST framework config" → check default permissions and auth
npx skillsauth add igorwarzocha/opencode-workflows security-djangoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Security audit patterns for Django applications covering critical settings, security middleware, CSRF protection, and common vulnerabilities.
</overview> <rules># ❌ CRITICAL: Hardcoded or committed
SECRET_KEY = 'django-insecure-abc123...'
SECRET_KEY = 'my-super-secret-key'
# ✓ From environment
import os
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
# ✓ Or use django-environ
import environ
env = environ.Env()
SECRET_KEY = env('SECRET_KEY')
Check: Is SECRET_KEY in .env and .env is in .gitignore?
# ❌ CRITICAL: Debug in production
DEBUG = True # Exposes full stack traces, settings, SQL queries
# ✓ Environment-controlled
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
# ❌ CRITICAL: Accept any host
ALLOWED_HOSTS = ['*']
# ❌ HIGH: Empty in production (500 errors, but still bad)
ALLOWED_HOSTS = []
# ✓ Explicit hosts
ALLOWED_HOSTS = ['example.com', 'www.example.com']
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', # MUST be first!
# ...
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Check: Is SecurityMiddleware present and near the top?
# ✓ Enable these in production
SECURE_BROWSER_XSS_FILTER = True # Deprecated but harmless
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_SSL_REDIRECT = True # Force HTTPS
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
</rules>
<vulnerabilities>
# ❌ CRITICAL: Globally disabled
MIDDLEWARE = [
# 'django.middleware.csrf.CsrfViewMiddleware', # Commented out!
]
# ❌ HIGH: Decorator abuse
@csrf_exempt
def payment_webhook(request): # MAY be OK for webhooks with other auth
...
@csrf_exempt
def update_profile(request): # MUST NOT do this!
...
Audit: Search for @csrf_exempt - each needs justification.
# ❌ Too permissive
CSRF_TRUSTED_ORIGINS = ['https://*']
# ✓ Explicit
CSRF_TRUSTED_ORIGINS = ['https://example.com', 'https://admin.example.com']
# ❌ Raw SQL with string formatting
User.objects.raw(f"SELECT * FROM users WHERE id = {user_id}")
cursor.execute(f"DELETE FROM logs WHERE date < '{date}'")
# ✓ Parameterized
User.objects.raw("SELECT * FROM users WHERE id = %s", [user_id])
cursor.execute("DELETE FROM logs WHERE date < %s", [date])
# ✓ ORM (safe by default)
User.objects.filter(id=user_id)
# ❌ User input in subprocess
import subprocess
subprocess.run(f"convert {user_filename} output.png", shell=True)
os.system(f"process {user_input}")
# ✓ Use arrays, avoid shell=True
subprocess.run(["convert", user_filename, "output.png"])
# ❌ User-controlled path
def download(request, filename):
return FileResponse(open(f'uploads/{filename}', 'rb'))
# ✓ Validate path
import os
def download(request, filename):
safe_name = os.path.basename(filename)
filepath = os.path.join(settings.UPLOAD_DIR, safe_name)
if not filepath.startswith(settings.UPLOAD_DIR):
raise Http404()
return FileResponse(open(filepath, 'rb'))
# ❌ No ownership check
class DocumentView(View):
def get(self, request, doc_id):
doc = Document.objects.get(id=doc_id)
return JsonResponse(doc.to_dict())
# ✓ Check ownership
class DocumentView(LoginRequiredMixin, View):
def get(self, request, doc_id):
doc = Document.objects.get(id=doc_id, owner=request.user)
return JsonResponse(doc.to_dict())
# ❌ No auth required
def admin_dashboard(request):
return render(request, 'admin/dashboard.html', {'users': User.objects.all()})
# ✓ Auth required
@login_required
@user_passes_test(lambda u: u.is_staff)
def admin_dashboard(request):
...
# Check DRF settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# ❌ SessionAuth without CSRF = vulnerable
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
# ❌ Allow any by default
'rest_framework.permissions.AllowAny',
# ✓ Require auth by default
'rest_framework.permissions.IsAuthenticated',
],
}
</vulnerabilities>
<commands>
# Check critical settings
rg "(SECRET_KEY|DEBUG|ALLOWED_HOSTS)" settings*.py
# Find csrf_exempt usage
rg "@csrf_exempt" . -g "*.py"
# Django deployment checklist (high signal)
python manage.py check --deploy
# Find raw SQL
rg "\.raw\(|cursor\.execute\(" . -g "*.py" -A 1
# Find subprocess/os.system
rg "(subprocess\.|os\.system|os\.popen)" . -g "*.py"
# Check for missing login_required
rg "^def " views.py | head -20 # Then check which have decorators
# Find shell=True
rg "shell\s*=\s*True" . -g "*.py"
</commands>
<checklist>
development
Handle structured co-authoring of professional documentation. Use for proposals, technical specs, and RFCs. Use proactively when a collaborative drafting process (Gathering -> Refinement -> Testing) is needed. Examples: - user: "Draft a technical RFC for the new API" -> follow Stage 1 context gathering - user: "Refine the introduction of this proposal" -> use iterative surgical edits - user: "Test if this document is clear for readers" -> run reader testing workflow
development
Handle Word document (.docx) creation, editing, and analysis with high-fidelity visual review. Use for professional reports, legal documents, and tracked changes. Use proactively when quality and precise formatting are critical. Examples: - user: "Create a professional report in Word" -> use python-docx with render loops - user: "Draft a legal contract with redlines" -> use ooxml redlining workflow - user: "Extract text from this DOCX while preserving structure" -> use pandoc markdown conversion
testing
Apply professional visual themes to documents and presentations. Use for styling artifacts with consistent color palettes and font pairings. Use proactively to quickly improve the aesthetic quality of deliverables. Examples: - user: "Apply a modern theme to this deck" -> use Modern Minimalist theme - user: "I want a tech aesthetic for this doc" -> apply Tech Innovation theme - user: "Create a custom theme for my project" -> generate new color/font specification
tools
Guide for creating effective opencode skills. Use for creating or updating skills that extend agent capabilities with specialized knowledge, workflows, or tool integrations. Examples: - user: "Create a skill for git workflows" → define SKILL.md with instructions and examples - user: "Add examples to my skill" → follow the user: "query" → action pattern - user: "Update skill description" → use literal block scalar and trigger contexts - user: "Structure a complex skill" → organize with scripts/ and references/ directories - user: "Validate my skill" → check structure, frontmatter, and discovery triggers