If you discover a security vulnerability in this project, please report it responsibly:
- DO NOT open a public issue
- Email the maintainer directly with details
- Allow reasonable time for a fix before public disclosure
NEVER commit sensitive data to version control:
- ✅ Use
.envfile for all secrets - ✅ Keep
.envin.gitignore - ✅ Use
.env.exampleas a template (without real values) - ❌ Never hardcode passwords, API keys, or secrets in code
Example .env structure:
SECRET_KEY=your-secret-key-here
DEBUG=True
EMAIL_HOST_PASSWORD=your-email-passwordGenerate a strong Django secret key:
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())- Minimum 50 characters
- Use random, unpredictable values
- Rotate regularly (especially after suspected compromise)
- Never reuse across environments
For Admin/User Accounts:
- Minimum 8 characters (enforced by Django validators)
- Mix of uppercase, lowercase, numbers, and symbols
- Avoid common passwords (Django checks against common password list)
- Use password managers for strong, unique passwords
Password Hashing:
- System uses Argon2 (if installed) or PBKDF2
- Passwords are never stored in plain text
- Password reset uses secure token-based system
Development:
- SQLite is fine for development
- Keep
db.sqlite3in.gitignore - Never commit database files with real user data
Production:
- Use PostgreSQL or MySQL
- Enable SSL/TLS for database connections
- Use strong database passwords
- Restrict database access to application server only
- Regular backups with encryption
Update config/settings.py or .env:
DEBUG=False
SECRET_KEY=<new-production-secret-key>
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com- REQUIRED for production
- Obtain SSL certificate (Let's Encrypt is free)
- Configure web server (Nginx/Apache) for HTTPS
- Enable HSTS (HTTP Strict Transport Security)
The following settings are automatically enabled when DEBUG=False:
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000Already configured in config/settings.py:
X-Frame-Options: DENY- Prevents clickjackingX-Content-Type-Options: nosniff- Prevents MIME sniffingX-XSS-Protection: 1; mode=block- XSS protectionReferrer-Policy: same-origin- Controls referrer information
- Enabled by default on all forms
- Use
{% csrf_token %}in all POST forms - AJAX requests must include CSRF token
Current configuration:
SESSION_COOKIE_AGE = 3600 # 1 hour
SESSION_COOKIE_HTTPONLY = True # Prevent JavaScript access
SESSION_COOKIE_SAMESITE = 'Lax' # CSRF protectionFor production, sessions are secure (HTTPS only).
Gmail Configuration:
- Enable 2-Factor Authentication
- Use App Passwords (not your main password)
- Never commit email credentials
SendGrid/Other SMTP:
- Use API keys instead of passwords where possible
- Rotate API keys regularly
- Monitor for unauthorized usage
If implementing file uploads:
- Validate file types and extensions
- Limit file sizes
- Scan for malware
- Store uploads outside web root
- Use unique, random filenames
The system includes basic rate limiting middleware:
- Login attempts are limited
- Account lockout after failed attempts
- Protects against brute force attacks
- Always use Django ORM (never raw SQL)
- If raw SQL is necessary, use parameterized queries
- Never concatenate user input into SQL
Good:
User.objects.filter(email=user_email)Bad:
cursor.execute(f"SELECT * FROM users WHERE email='{user_email}'")- Django auto-escapes template variables
- Use
|safefilter only for trusted content - Sanitize user input before display
- Admin: Full access
- Manager: Business operations
- User: Limited access
- Viewer: Read-only
Enforce permissions in views:
from django.contrib.auth.decorators import login_required
from apps.accounts.decorators import role_required
@login_required
@role_required(['Admin', 'Manager'])
def sensitive_view(request):
# Only Admin and Manager can access
pass- Validate all user input
- Use Django forms for automatic validation
- Sanitize data before processing
- Never expose stack traces to users (set
DEBUG=False) - Log errors securely
- Use custom error pages (400, 403, 404, 500)
- Log security events (failed logins, permission denials)
- Protect log files (don't commit to version control)
- Rotate logs regularly
- Keep Django and packages updated
- Run
pip list --outdatedregularly - Monitor security advisories
- Use
pip-auditto check for vulnerabilities:
pip install pip-audit
pip-auditBefore deploying to production:
-
DEBUG=Falsein production - Strong, unique
SECRET_KEY -
ALLOWED_HOSTSconfigured correctly - HTTPS/SSL enabled
- Database using PostgreSQL with strong password
- Email configured with secure credentials
- Static files collected (
python manage.py collectstatic) - Media files stored securely
- Backups configured and tested
- Monitoring and logging enabled
- Security headers verified
- Dependencies updated
-
.envfile secured (not in version control) - Admin scripts with hardcoded passwords removed
- Rate limiting configured
- Error pages customized (no debug info)
- Review access logs for suspicious activity
- Check for failed login attempts
- Update dependencies
- Review user accounts and permissions
- Test backup restoration
- Security audit
- Rotate secrets and API keys
- Review and update security policies
❌ Bad:
admin_password = 'admin123'
EMAIL_HOST_PASSWORD = 'mypassword'✅ Good:
admin_password = os.getenv('ADMIN_PASSWORD')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')❌ Bad:
DEBUG = True # In production✅ Good:
DEBUG = os.getenv('DEBUG', 'False') == 'True'❌ Bad:
- admin/admin
- password123
- 12345678
✅ Good:
- Use password generators
- Minimum 12 characters for admin accounts
- Mix of character types
❌ Bad:
- Committing
.envto GitHub - Hardcoding
SECRET_KEYin settings.py - Sharing secrets in chat/email
✅ Good:
- Use environment variables
- Use secret management tools
- Rotate keys regularly
If a security breach occurs:
-
Immediate Actions:
- Take affected systems offline if necessary
- Change all passwords and secrets
- Review access logs
-
Investigation:
- Determine scope of breach
- Identify vulnerability
- Document timeline
-
Remediation:
- Fix vulnerability
- Update security measures
- Notify affected users (if applicable)
-
Post-Incident:
- Update security policies
- Implement additional safeguards
- Train team on lessons learned
For security concerns, please contact the project maintainer.
Remember: Security is everyone's responsibility! 🔒