Security-First Development: How djust Protects Your Application by Default
Security vulnerabilities don't wait for your next sprint planning session. They exploit weaknesses the moment your code ships. That's why djust now includes comprehensive security hardening features that protect your application by default, without requiring you to become a security expert.
With PR #40, we've added a complete security toolkit that covers Python, JavaScript, Rust, and your CI/CD pipeline. Let's explore what's included and how it protects you.
The Security Utilities Module
The new djust.security module provides battle-tested utilities for handling untrusted input safely.
Preventing Prototype Pollution with safe_setattr()
Prototype pollution attacks occur when attackers inject dangerous attribute names like __class__ or __proto__ through user input. These attacks can lead to authentication bypass, code execution, or denial of service.
djust's safe_setattr() blocks over 60 dangerous attributes automatically:
from djust.security import safe_setattr
# Instead of this (DANGEROUS):
for key, value in user_params.items():
setattr(obj, key, value) # Attacker could set __class__!
# Use this (SAFE):
for key, value in user_params.items():
safe_setattr(obj, key, value) # Blocks __class__, __proto__, etc.
Stopping Log Injection with sanitize_for_log()
Log injection attacks allow attackers to forge log entries, inject ANSI escape codes to manipulate terminals, or flood your logs with massive strings. The sanitize_for_log() function handles all of this:
from djust.security import sanitize_for_log
# Instead of this (DANGEROUS):
logger.info(f"User searched for: {user_query}")
# Use this (SAFE):
logger.info(f"User searched for: {sanitize_for_log(user_query)}")
The function strips ANSI escape sequences, replaces control characters, collapses newlines, and truncates excessively long strings.
DEBUG-Aware Error Handling
Exposing stack traces in production is a security vulnerability. They reveal file paths, code structure, and dependency versions to attackers. The handle_exception() function provides safe error responses that respect your DEBUG setting:
from djust.security import handle_exception
try:
process_user_request()
except Exception as e:
# Logs with stack trace in DEBUG, without in production
# Returns detailed error in DEBUG, generic message in production
response = handle_exception(
e,
error_type="event",
event_name="submit",
logger=logger
)
JavaScript Security Utilities
Client-side security matters too. djust now includes security.js with utilities for safe DOM manipulation:
// Safe innerHTML (prevents XSS via DOMParser sanitization)
djustSecurity.safeSetInnerHTML(element, untrustedHTML);
// Safe object merging (blocks __proto__ pollution)
const merged = djustSecurity.safeObjectAssign({}, untrustedData);
// Safe logging (strips control characters)
console.log(djustSecurity.sanitizeForLog(userInput));
The safeSetInnerHTML() function parses HTML through DOMParser, removes script tags and inline event handlers, and strips dangerous URL schemes like javascript:, data:, and vbscript:.
Automated Security Scanning in CI/CD
Security can't depend on developers remembering to run checks manually. Our CI pipeline now includes a dedicated security-scan job that runs automatically on every pull request:
- Bandit - Scans Python code for common security issues
- Safety - Checks Python dependencies for known vulnerabilities
- cargo-audit - Scans Rust dependencies for security advisories
- npm audit - Checks JavaScript dependencies for vulnerabilities
- ESLint security plugin - Catches JavaScript security anti-patterns
Vulnerable code doesn't merge. Period.
Pre-commit Hooks for Early Detection
Why wait for CI when you can catch issues before you commit? Our pre-commit configuration includes:
repos:
- repo: https://github.com/PyCQA/bandit
hooks:
- id: bandit # Python security linting
- repo: https://github.com/Yelp/detect-secrets
hooks:
- id: detect-secrets # Credential detection
- repo: local
hooks:
- id: cargo-audit # Rust dependency vulnerabilities
stages: [pre-push]
Install them with pre-commit install and security checks run automatically every time you commit.
Security Guidelines for Contributors
We've documented our security requirements in docs/SECURITY_GUIDELINES.md, including:
- Banned patterns (what NOT to do)
- Required utilities (what to use instead)
- Code review checklist for security issues
- Common vulnerabilities with prevention examples
- Manual testing procedures for security-sensitive changes
What This Means for You
As a djust developer, you get:
- Protection by default - Security utilities are ready to import and use
- Automated enforcement - CI catches security issues before they ship
- Early feedback - Pre-commit hooks flag problems immediately
- Clear guidance - Documentation tells you exactly what to do
Security is no longer something you need to remember. It's built into your workflow.
Getting Started
Update to the latest djust version and start using the security utilities:
pip install --upgrade djust
from djust.security import (
safe_setattr,
sanitize_for_log,
handle_exception,
)
Check out the full Security Guidelines for detailed documentation and examples.
Security is a journey, not a destination. These features represent our commitment to making djust applications secure by default. Have suggestions for additional security features? Open an issue or submit a PR - we'd love to hear from you.
Related Posts
Faster Templates, Smarter Hydration: Performance Optimizations in djust 0.1.6
djust 0.1.6 introduces AST optimization for 5-15% faster rendering, lazy hydration for 20-40% memory reduction, TurboNav integration, and improved whitespace preservation.
Full Django Template Compatibility: URL Tags, Comparison Operators, and Auto-Serialization
djust v0.1.6 brings major template system improvements including {% url %} tag support, {% include %} fixes, comparison operators in {% if %} conditions, and automatic Django type serialization.
Introducing djust: Phoenix LiveView for Django
We are excited to announce djust, a framework that brings Phoenix LiveView-style reactive server-side rendering to Django. Build real-time, interactive web applications with Python - no JavaScript required.