@chc880/everything-antigravity 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -0
  3. package/assets/rules/common/coding-style.md +53 -0
  4. package/assets/rules/common/git-workflow.md +47 -0
  5. package/assets/rules/common/patterns.md +36 -0
  6. package/assets/rules/common/performance.md +21 -0
  7. package/assets/rules/common/security.md +34 -0
  8. package/assets/rules/common/testing.md +29 -0
  9. package/assets/rules/golang/coding-style.md +40 -0
  10. package/assets/rules/golang/patterns.md +44 -0
  11. package/assets/rules/golang/security.md +33 -0
  12. package/assets/rules/golang/testing.md +30 -0
  13. package/assets/rules/python/coding-style.md +52 -0
  14. package/assets/rules/python/patterns.md +39 -0
  15. package/assets/rules/python/security.md +30 -0
  16. package/assets/rules/python/testing.md +38 -0
  17. package/assets/rules/typescript/coding-style.md +44 -0
  18. package/assets/rules/typescript/patterns.md +50 -0
  19. package/assets/rules/typescript/security.md +27 -0
  20. package/assets/rules/typescript/testing.md +24 -0
  21. package/assets/skills/agent-guides/SKILL.md +40 -0
  22. package/assets/skills/agent-guides/references/architect.md +209 -0
  23. package/assets/skills/agent-guides/references/build-error-resolver.md +530 -0
  24. package/assets/skills/agent-guides/references/code-reviewer.md +102 -0
  25. package/assets/skills/agent-guides/references/database-reviewer.md +652 -0
  26. package/assets/skills/agent-guides/references/doc-updater.md +450 -0
  27. package/assets/skills/agent-guides/references/e2e-runner.md +795 -0
  28. package/assets/skills/agent-guides/references/go-build-resolver.md +366 -0
  29. package/assets/skills/agent-guides/references/go-reviewer.md +265 -0
  30. package/assets/skills/agent-guides/references/planner.md +117 -0
  31. package/assets/skills/agent-guides/references/python-reviewer.md +467 -0
  32. package/assets/skills/agent-guides/references/refactor-cleaner.md +304 -0
  33. package/assets/skills/agent-guides/references/security-reviewer.md +543 -0
  34. package/assets/skills/agent-guides/references/tdd-guide.md +278 -0
  35. package/assets/skills/backend-patterns/SKILL.md +587 -0
  36. package/assets/skills/clickhouse-io/SKILL.md +429 -0
  37. package/assets/skills/coding-standards/SKILL.md +520 -0
  38. package/assets/skills/cpp-testing/SKILL.md +322 -0
  39. package/assets/skills/django-patterns/SKILL.md +733 -0
  40. package/assets/skills/django-security/SKILL.md +592 -0
  41. package/assets/skills/django-tdd/SKILL.md +728 -0
  42. package/assets/skills/django-verification/SKILL.md +460 -0
  43. package/assets/skills/frontend-patterns/SKILL.md +631 -0
  44. package/assets/skills/golang-patterns/SKILL.md +673 -0
  45. package/assets/skills/golang-testing/SKILL.md +719 -0
  46. package/assets/skills/java-coding-standards/SKILL.md +138 -0
  47. package/assets/skills/jpa-patterns/SKILL.md +141 -0
  48. package/assets/skills/knowledge-management/SKILL.md +77 -0
  49. package/assets/skills/nutrient-document-processing/SKILL.md +165 -0
  50. package/assets/skills/postgres-patterns/SKILL.md +146 -0
  51. package/assets/skills/python-patterns/SKILL.md +749 -0
  52. package/assets/skills/python-testing/SKILL.md +815 -0
  53. package/assets/skills/security-hardening/SKILL.md +76 -0
  54. package/assets/skills/security-review/SKILL.md +494 -0
  55. package/assets/skills/security-review/cloud-infrastructure-security.md +361 -0
  56. package/assets/skills/springboot-patterns/SKILL.md +304 -0
  57. package/assets/skills/springboot-security/SKILL.md +119 -0
  58. package/assets/skills/springboot-tdd/SKILL.md +157 -0
  59. package/assets/skills/springboot-verification/SKILL.md +100 -0
  60. package/assets/skills/tdd-workflow/SKILL.md +409 -0
  61. package/assets/workflows/build-fix.md +50 -0
  62. package/assets/workflows/code-review.md +61 -0
  63. package/assets/workflows/e2e.md +65 -0
  64. package/assets/workflows/go-build.md +39 -0
  65. package/assets/workflows/go-review.md +44 -0
  66. package/assets/workflows/go-test.md +61 -0
  67. package/assets/workflows/plan.md +93 -0
  68. package/assets/workflows/python-review.md +95 -0
  69. package/assets/workflows/setup-pm.md +36 -0
  70. package/assets/workflows/tdd.md +75 -0
  71. package/assets/workflows/verify.md +81 -0
  72. package/bin/cli.js +69 -0
  73. package/lib/installer.js +301 -0
  74. package/package.json +34 -0
@@ -0,0 +1,592 @@
1
+ ---
2
+ name: django-security
3
+ description: Django security best practices, authentication, authorization, CSRF protection, SQL injection prevention, XSS prevention, and secure deployment configurations.
4
+ ---
5
+
6
+ # Django Security Best Practices
7
+
8
+ Comprehensive security guidelines for Django applications to protect against common vulnerabilities.
9
+
10
+ ## When to Activate
11
+
12
+ - Setting up Django authentication and authorization
13
+ - Implementing user permissions and roles
14
+ - Configuring production security settings
15
+ - Reviewing Django application for security issues
16
+ - Deploying Django applications to production
17
+
18
+ ## Core Security Settings
19
+
20
+ ### Production Settings Configuration
21
+
22
+ ```python
23
+ # settings/production.py
24
+ import os
25
+
26
+ DEBUG = False # CRITICAL: Never use True in production
27
+
28
+ ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
29
+
30
+ # Security headers
31
+ SECURE_SSL_REDIRECT = True
32
+ SESSION_COOKIE_SECURE = True
33
+ CSRF_COOKIE_SECURE = True
34
+ SECURE_HSTS_SECONDS = 31536000 # 1 year
35
+ SECURE_HSTS_INCLUDE_SUBDOMAINS = True
36
+ SECURE_HSTS_PRELOAD = True
37
+ SECURE_CONTENT_TYPE_NOSNIFF = True
38
+ SECURE_BROWSER_XSS_FILTER = True
39
+ X_FRAME_OPTIONS = 'DENY'
40
+
41
+ # HTTPS and Cookies
42
+ SESSION_COOKIE_HTTPONLY = True
43
+ CSRF_COOKIE_HTTPONLY = True
44
+ SESSION_COOKIE_SAMESITE = 'Lax'
45
+ CSRF_COOKIE_SAMESITE = 'Lax'
46
+
47
+ # Secret key (must be set via environment variable)
48
+ SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
49
+ if not SECRET_KEY:
50
+ raise ImproperlyConfigured('DJANGO_SECRET_KEY environment variable is required')
51
+
52
+ # Password validation
53
+ AUTH_PASSWORD_VALIDATORS = [
54
+ {
55
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
56
+ },
57
+ {
58
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
59
+ 'OPTIONS': {
60
+ 'min_length': 12,
61
+ }
62
+ },
63
+ {
64
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
65
+ },
66
+ {
67
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
68
+ },
69
+ ]
70
+ ```
71
+
72
+ ## Authentication
73
+
74
+ ### Custom User Model
75
+
76
+ ```python
77
+ # apps/users/models.py
78
+ from django.contrib.auth.models import AbstractUser
79
+ from django.db import models
80
+
81
+ class User(AbstractUser):
82
+ """Custom user model for better security."""
83
+
84
+ email = models.EmailField(unique=True)
85
+ phone = models.CharField(max_length=20, blank=True)
86
+
87
+ USERNAME_FIELD = 'email' # Use email as username
88
+ REQUIRED_FIELDS = ['username']
89
+
90
+ class Meta:
91
+ db_table = 'users'
92
+ verbose_name = 'User'
93
+ verbose_name_plural = 'Users'
94
+
95
+ def __str__(self):
96
+ return self.email
97
+
98
+ # settings/base.py
99
+ AUTH_USER_MODEL = 'users.User'
100
+ ```
101
+
102
+ ### Password Hashing
103
+
104
+ ```python
105
+ # Django uses PBKDF2 by default. For stronger security:
106
+ PASSWORD_HASHERS = [
107
+ 'django.contrib.auth.hashers.Argon2PasswordHasher',
108
+ 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
109
+ 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
110
+ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
111
+ ]
112
+ ```
113
+
114
+ ### Session Management
115
+
116
+ ```python
117
+ # Session configuration
118
+ SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # Or 'db'
119
+ SESSION_CACHE_ALIAS = 'default'
120
+ SESSION_COOKIE_AGE = 3600 * 24 * 7 # 1 week
121
+ SESSION_SAVE_EVERY_REQUEST = False
122
+ SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Better UX, but less secure
123
+ ```
124
+
125
+ ## Authorization
126
+
127
+ ### Permissions
128
+
129
+ ```python
130
+ # models.py
131
+ from django.db import models
132
+ from django.contrib.auth.models import Permission
133
+
134
+ class Post(models.Model):
135
+ title = models.CharField(max_length=200)
136
+ content = models.TextField()
137
+ author = models.ForeignKey(User, on_delete=models.CASCADE)
138
+
139
+ class Meta:
140
+ permissions = [
141
+ ('can_publish', 'Can publish posts'),
142
+ ('can_edit_others', 'Can edit posts of others'),
143
+ ]
144
+
145
+ def user_can_edit(self, user):
146
+ """Check if user can edit this post."""
147
+ return self.author == user or user.has_perm('app.can_edit_others')
148
+
149
+ # views.py
150
+ from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
151
+ from django.views.generic import UpdateView
152
+
153
+ class PostUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
154
+ model = Post
155
+ permission_required = 'app.can_edit_others'
156
+ raise_exception = True # Return 403 instead of redirect
157
+
158
+ def get_queryset(self):
159
+ """Only allow users to edit their own posts."""
160
+ return Post.objects.filter(author=self.request.user)
161
+ ```
162
+
163
+ ### Custom Permissions
164
+
165
+ ```python
166
+ # permissions.py
167
+ from rest_framework import permissions
168
+
169
+ class IsOwnerOrReadOnly(permissions.BasePermission):
170
+ """Allow only owners to edit objects."""
171
+
172
+ def has_object_permission(self, request, view, obj):
173
+ # Read permissions allowed for any request
174
+ if request.method in permissions.SAFE_METHODS:
175
+ return True
176
+
177
+ # Write permissions only for owner
178
+ return obj.author == request.user
179
+
180
+ class IsAdminOrReadOnly(permissions.BasePermission):
181
+ """Allow admins to do anything, others read-only."""
182
+
183
+ def has_permission(self, request, view):
184
+ if request.method in permissions.SAFE_METHODS:
185
+ return True
186
+ return request.user and request.user.is_staff
187
+
188
+ class IsVerifiedUser(permissions.BasePermission):
189
+ """Allow only verified users."""
190
+
191
+ def has_permission(self, request, view):
192
+ return request.user and request.user.is_authenticated and request.user.is_verified
193
+ ```
194
+
195
+ ### Role-Based Access Control (RBAC)
196
+
197
+ ```python
198
+ # models.py
199
+ from django.contrib.auth.models import AbstractUser, Group
200
+
201
+ class User(AbstractUser):
202
+ ROLE_CHOICES = [
203
+ ('admin', 'Administrator'),
204
+ ('moderator', 'Moderator'),
205
+ ('user', 'Regular User'),
206
+ ]
207
+ role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user')
208
+
209
+ def is_admin(self):
210
+ return self.role == 'admin' or self.is_superuser
211
+
212
+ def is_moderator(self):
213
+ return self.role in ['admin', 'moderator']
214
+
215
+ # Mixins
216
+ class AdminRequiredMixin:
217
+ """Mixin to require admin role."""
218
+
219
+ def dispatch(self, request, *args, **kwargs):
220
+ if not request.user.is_authenticated or not request.user.is_admin():
221
+ from django.core.exceptions import PermissionDenied
222
+ raise PermissionDenied
223
+ return super().dispatch(request, *args, **kwargs)
224
+ ```
225
+
226
+ ## SQL Injection Prevention
227
+
228
+ ### Django ORM Protection
229
+
230
+ ```python
231
+ # GOOD: Django ORM automatically escapes parameters
232
+ def get_user(username):
233
+ return User.objects.get(username=username) # Safe
234
+
235
+ # GOOD: Using parameters with raw()
236
+ def search_users(query):
237
+ return User.objects.raw('SELECT * FROM users WHERE username = %s', [query])
238
+
239
+ # BAD: Never directly interpolate user input
240
+ def get_user_bad(username):
241
+ return User.objects.raw(f'SELECT * FROM users WHERE username = {username}') # VULNERABLE!
242
+
243
+ # GOOD: Using filter with proper escaping
244
+ def get_users_by_email(email):
245
+ return User.objects.filter(email__iexact=email) # Safe
246
+
247
+ # GOOD: Using Q objects for complex queries
248
+ from django.db.models import Q
249
+ def search_users_complex(query):
250
+ return User.objects.filter(
251
+ Q(username__icontains=query) |
252
+ Q(email__icontains=query)
253
+ ) # Safe
254
+ ```
255
+
256
+ ### Extra Security with raw()
257
+
258
+ ```python
259
+ # If you must use raw SQL, always use parameters
260
+ User.objects.raw(
261
+ 'SELECT * FROM users WHERE email = %s AND status = %s',
262
+ [user_input_email, status]
263
+ )
264
+ ```
265
+
266
+ ## XSS Prevention
267
+
268
+ ### Template Escaping
269
+
270
+ ```django
271
+ {# Django auto-escapes variables by default - SAFE #}
272
+ {{ user_input }} {# Escaped HTML #}
273
+
274
+ {# Explicitly mark safe only for trusted content #}
275
+ {{ trusted_html|safe }} {# Not escaped #}
276
+
277
+ {# Use template filters for safe HTML #}
278
+ {{ user_input|escape }} {# Same as default #}
279
+ {{ user_input|striptags }} {# Remove all HTML tags #}
280
+
281
+ {# JavaScript escaping #}
282
+ <script>
283
+ var username = {{ username|escapejs }};
284
+ </script>
285
+ ```
286
+
287
+ ### Safe String Handling
288
+
289
+ ```python
290
+ from django.utils.safestring import mark_safe
291
+ from django.utils.html import escape
292
+
293
+ # BAD: Never mark user input as safe without escaping
294
+ def render_bad(user_input):
295
+ return mark_safe(user_input) # VULNERABLE!
296
+
297
+ # GOOD: Escape first, then mark safe
298
+ def render_good(user_input):
299
+ return mark_safe(escape(user_input))
300
+
301
+ # GOOD: Use format_html for HTML with variables
302
+ from django.utils.html import format_html
303
+
304
+ def greet_user(username):
305
+ return format_html('<span class="user">{}</span>', escape(username))
306
+ ```
307
+
308
+ ### HTTP Headers
309
+
310
+ ```python
311
+ # settings.py
312
+ SECURE_CONTENT_TYPE_NOSNIFF = True # Prevent MIME sniffing
313
+ SECURE_BROWSER_XSS_FILTER = True # Enable XSS filter
314
+ X_FRAME_OPTIONS = 'DENY' # Prevent clickjacking
315
+
316
+ # Custom middleware
317
+ from django.conf import settings
318
+
319
+ class SecurityHeaderMiddleware:
320
+ def __init__(self, get_response):
321
+ self.get_response = get_response
322
+
323
+ def __call__(self, request):
324
+ response = self.get_response(request)
325
+ response['X-Content-Type-Options'] = 'nosniff'
326
+ response['X-Frame-Options'] = 'DENY'
327
+ response['X-XSS-Protection'] = '1; mode=block'
328
+ response['Content-Security-Policy'] = "default-src 'self'"
329
+ return response
330
+ ```
331
+
332
+ ## CSRF Protection
333
+
334
+ ### Default CSRF Protection
335
+
336
+ ```python
337
+ # settings.py - CSRF is enabled by default
338
+ CSRF_COOKIE_SECURE = True # Only send over HTTPS
339
+ CSRF_COOKIE_HTTPONLY = True # Prevent JavaScript access
340
+ CSRF_COOKIE_SAMESITE = 'Lax' # Prevent CSRF in some cases
341
+ CSRF_TRUSTED_ORIGINS = ['https://example.com'] # Trusted domains
342
+
343
+ # Template usage
344
+ <form method="post">
345
+ {% csrf_token %}
346
+ {{ form.as_p }}
347
+ <button type="submit">Submit</button>
348
+ </form>
349
+
350
+ # AJAX requests
351
+ function getCookie(name) {
352
+ let cookieValue = null;
353
+ if (document.cookie && document.cookie !== '') {
354
+ const cookies = document.cookie.split(';');
355
+ for (let i = 0; i < cookies.length; i++) {
356
+ const cookie = cookies[i].trim();
357
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
358
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
359
+ break;
360
+ }
361
+ }
362
+ }
363
+ return cookieValue;
364
+ }
365
+
366
+ fetch('/api/endpoint/', {
367
+ method: 'POST',
368
+ headers: {
369
+ 'X-CSRFToken': getCookie('csrftoken'),
370
+ 'Content-Type': 'application/json',
371
+ },
372
+ body: JSON.stringify(data)
373
+ });
374
+ ```
375
+
376
+ ### Exempting Views (Use Carefully)
377
+
378
+ ```python
379
+ from django.views.decorators.csrf import csrf_exempt
380
+
381
+ @csrf_exempt # Only use when absolutely necessary!
382
+ def webhook_view(request):
383
+ # Webhook from external service
384
+ pass
385
+ ```
386
+
387
+ ## File Upload Security
388
+
389
+ ### File Validation
390
+
391
+ ```python
392
+ import os
393
+ from django.core.exceptions import ValidationError
394
+
395
+ def validate_file_extension(value):
396
+ """Validate file extension."""
397
+ ext = os.path.splitext(value.name)[1]
398
+ valid_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.pdf']
399
+ if not ext.lower() in valid_extensions:
400
+ raise ValidationError('Unsupported file extension.')
401
+
402
+ def validate_file_size(value):
403
+ """Validate file size (max 5MB)."""
404
+ filesize = value.size
405
+ if filesize > 5 * 1024 * 1024:
406
+ raise ValidationError('File too large. Max size is 5MB.')
407
+
408
+ # models.py
409
+ class Document(models.Model):
410
+ file = models.FileField(
411
+ upload_to='documents/',
412
+ validators=[validate_file_extension, validate_file_size]
413
+ )
414
+ ```
415
+
416
+ ### Secure File Storage
417
+
418
+ ```python
419
+ # settings.py
420
+ MEDIA_ROOT = '/var/www/media/'
421
+ MEDIA_URL = '/media/'
422
+
423
+ # Use a separate domain for media in production
424
+ MEDIA_DOMAIN = 'https://media.example.com'
425
+
426
+ # Don't serve user uploads directly
427
+ # Use whitenoise or a CDN for static files
428
+ # Use a separate server or S3 for media files
429
+ ```
430
+
431
+ ## API Security
432
+
433
+ ### Rate Limiting
434
+
435
+ ```python
436
+ # settings.py
437
+ REST_FRAMEWORK = {
438
+ 'DEFAULT_THROTTLE_CLASSES': [
439
+ 'rest_framework.throttling.AnonRateThrottle',
440
+ 'rest_framework.throttling.UserRateThrottle'
441
+ ],
442
+ 'DEFAULT_THROTTLE_RATES': {
443
+ 'anon': '100/day',
444
+ 'user': '1000/day',
445
+ 'upload': '10/hour',
446
+ }
447
+ }
448
+
449
+ # Custom throttle
450
+ from rest_framework.throttling import UserRateThrottle
451
+
452
+ class BurstRateThrottle(UserRateThrottle):
453
+ scope = 'burst'
454
+ rate = '60/min'
455
+
456
+ class SustainedRateThrottle(UserRateThrottle):
457
+ scope = 'sustained'
458
+ rate = '1000/day'
459
+ ```
460
+
461
+ ### Authentication for APIs
462
+
463
+ ```python
464
+ # settings.py
465
+ REST_FRAMEWORK = {
466
+ 'DEFAULT_AUTHENTICATION_CLASSES': [
467
+ 'rest_framework.authentication.TokenAuthentication',
468
+ 'rest_framework.authentication.SessionAuthentication',
469
+ 'rest_framework_simplejwt.authentication.JWTAuthentication',
470
+ ],
471
+ 'DEFAULT_PERMISSION_CLASSES': [
472
+ 'rest_framework.permissions.IsAuthenticated',
473
+ ],
474
+ }
475
+
476
+ # views.py
477
+ from rest_framework.decorators import api_view, permission_classes
478
+ from rest_framework.permissions import IsAuthenticated
479
+
480
+ @api_view(['GET', 'POST'])
481
+ @permission_classes([IsAuthenticated])
482
+ def protected_view(request):
483
+ return Response({'message': 'You are authenticated'})
484
+ ```
485
+
486
+ ## Security Headers
487
+
488
+ ### Content Security Policy
489
+
490
+ ```python
491
+ # settings.py
492
+ CSP_DEFAULT_SRC = "'self'"
493
+ CSP_SCRIPT_SRC = "'self' https://cdn.example.com"
494
+ CSP_STYLE_SRC = "'self' 'unsafe-inline'"
495
+ CSP_IMG_SRC = "'self' data: https:"
496
+ CSP_CONNECT_SRC = "'self' https://api.example.com"
497
+
498
+ # Middleware
499
+ class CSPMiddleware:
500
+ def __init__(self, get_response):
501
+ self.get_response = get_response
502
+
503
+ def __call__(self, request):
504
+ response = self.get_response(request)
505
+ response['Content-Security-Policy'] = (
506
+ f"default-src {CSP_DEFAULT_SRC}; "
507
+ f"script-src {CSP_SCRIPT_SRC}; "
508
+ f"style-src {CSP_STYLE_SRC}; "
509
+ f"img-src {CSP_IMG_SRC}; "
510
+ f"connect-src {CSP_CONNECT_SRC}"
511
+ )
512
+ return response
513
+ ```
514
+
515
+ ## Environment Variables
516
+
517
+ ### Managing Secrets
518
+
519
+ ```python
520
+ # Use python-decouple or django-environ
521
+ import environ
522
+
523
+ env = environ.Env(
524
+ # set casting, default value
525
+ DEBUG=(bool, False)
526
+ )
527
+
528
+ # reading .env file
529
+ environ.Env.read_env()
530
+
531
+ SECRET_KEY = env('DJANGO_SECRET_KEY')
532
+ DATABASE_URL = env('DATABASE_URL')
533
+ ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
534
+
535
+ # .env file (never commit this)
536
+ DEBUG=False
537
+ SECRET_KEY=your-secret-key-here
538
+ DATABASE_URL=postgresql://user:password@localhost:5432/dbname
539
+ ALLOWED_HOSTS=example.com,www.example.com
540
+ ```
541
+
542
+ ## Logging Security Events
543
+
544
+ ```python
545
+ # settings.py
546
+ LOGGING = {
547
+ 'version': 1,
548
+ 'disable_existing_loggers': False,
549
+ 'handlers': {
550
+ 'file': {
551
+ 'level': 'WARNING',
552
+ 'class': 'logging.FileHandler',
553
+ 'filename': '/var/log/django/security.log',
554
+ },
555
+ 'console': {
556
+ 'level': 'INFO',
557
+ 'class': 'logging.StreamHandler',
558
+ },
559
+ },
560
+ 'loggers': {
561
+ 'django.security': {
562
+ 'handlers': ['file', 'console'],
563
+ 'level': 'WARNING',
564
+ 'propagate': True,
565
+ },
566
+ 'django.request': {
567
+ 'handlers': ['file'],
568
+ 'level': 'ERROR',
569
+ 'propagate': False,
570
+ },
571
+ },
572
+ }
573
+ ```
574
+
575
+ ## Quick Security Checklist
576
+
577
+ | Check | Description |
578
+ |-------|-------------|
579
+ | `DEBUG = False` | Never run with DEBUG in production |
580
+ | HTTPS only | Force SSL, secure cookies |
581
+ | Strong secrets | Use environment variables for SECRET_KEY |
582
+ | Password validation | Enable all password validators |
583
+ | CSRF protection | Enabled by default, don't disable |
584
+ | XSS prevention | Django auto-escapes, don't use `&#124;safe` with user input |
585
+ | SQL injection | Use ORM, never concatenate strings in queries |
586
+ | File uploads | Validate file type and size |
587
+ | Rate limiting | Throttle API endpoints |
588
+ | Security headers | CSP, X-Frame-Options, HSTS |
589
+ | Logging | Log security events |
590
+ | Updates | Keep Django and dependencies updated |
591
+
592
+ Remember: Security is a process, not a product. Regularly review and update your security practices.