# Vulnerable: exec() with format strings and user input
from django.http import JsonResponse
from django.views import View
import json
# Extremely dangerous: exec() with f-string
class DynamicCodeView(View):
def post(self, request):
action = request.POST.get('action', '')
target = request.POST.get('target', '')
value = request.POST.get('value', '')
try:
# CRITICAL: exec() with f-string containing user input
code = f"{action}('{target}', '{value}')"
exec(code)
return JsonResponse({'status': 'executed'})
except Exception as e:
return JsonResponse({'error': str(e)})
# Another dangerous pattern with .format()
def execute_dynamic_operation(request):
operation_template = request.POST.get('template', '')
parameters = json.loads(request.POST.get('params', '{}'))
try:
# Dangerous: format() with user input in exec()
formatted_code = operation_template.format(**parameters)
exec(formatted_code)
return JsonResponse({'result': 'operation_completed'})
except Exception as e:
return JsonResponse({'error': str(e)})
# Configuration execution
def apply_user_config(request):
config_template = request.POST.get('config', '')
config_vars = json.loads(request.POST.get('variables', '{}'))
# Dangerous: exec() with formatted configuration
try:
# User can inject: settings.DEBUG = True; __import__('os').system('rm -rf /')
config_code = config_template.format(**config_vars)
exec(config_code)
return JsonResponse({'status': 'config_applied'})
except Exception as e:
return JsonResponse({'error': str(e)})
# Database operation execution
def execute_db_operation(request):
operation = request.POST.get('operation', '')
table = request.POST.get('table', '')
conditions = request.POST.get('conditions', '')
# Dangerous: exec() for database operations
try:
db_code = f"result = MyModel.objects.{operation}({conditions})"
local_vars = {}
exec(db_code, {'MyModel': MyModel}, local_vars)
return JsonResponse({'result': str(local_vars.get('result', ''))})
except Exception as e:
return JsonResponse({'error': str(e)})
# Secure: Safe alternatives to exec() with format strings
from django.http import JsonResponse
from django.views import View
from django.core.exceptions import ValidationError
import json
# Safe: Predefined operations without exec()
class SafeDynamicOperationView(View):
def post(self, request):
action = request.POST.get('action', '')
target = request.POST.get('target', '')
value = request.POST.get('value', '')
try:
# Safe: Use predefined operations
result = self.execute_safe_operation(action, target, value)
return JsonResponse({'result': result})
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
def execute_safe_operation(self, action, target, value):
# Validate action
allowed_actions = {
'create': self.create_object,
'update': self.update_object,
'delete': self.delete_object,
'calculate': self.calculate_value
}
if action not in allowed_actions:
raise ValidationError('Action not allowed')
# Validate target and value
validated_target = self.validate_target(target)
validated_value = self.validate_value(value)
# Execute safe operation
return allowed_actions[action](validated_target, validated_value)
def validate_target(self, target):
# Only allow specific target formats
allowed_targets = ['user_profile', 'user_settings', 'user_preferences']
if target not in allowed_targets:
raise ValidationError('Target not allowed')
return target
def validate_value(self, value):
# Validate value format and content
if not value or len(value) > 100:
raise ValidationError('Invalid value')
# Additional validation based on context
try:
# Try to parse as JSON for structured data
parsed_value = json.loads(value)
return parsed_value
except json.JSONDecodeError:
# Treat as string if not JSON
return str(value)
def create_object(self, target, value):
# Safe object creation
if target == 'user_profile':
return f"Created profile with data: {value}"
# Add other safe creations
return "Object created"
def update_object(self, target, value):
# Safe object update
return f"Updated {target} with value: {value}"
def delete_object(self, target, value):
# Safe object deletion
return f"Deleted {target}: {value}"
def calculate_value(self, target, value):
# Safe calculation
try:
if isinstance(value, (int, float)):
return value * 2
return f"Calculated result for {target}"
except (TypeError, ValueError):
raise ValidationError('Invalid calculation input')
# Safe: Configuration management
def safe_apply_user_config(request):
try:
config_data = json.loads(request.body)
# Validate configuration structure
validated_config = validate_config_structure(config_data)
# Apply configuration safely
apply_validated_config(validated_config)
return JsonResponse({'status': 'config_applied'})
except (json.JSONDecodeError, ValidationError) as e:
return JsonResponse({'error': 'Invalid configuration'}, status=400)
def validate_config_structure(config):
if not isinstance(config, dict):
raise ValidationError('Configuration must be a dictionary')
allowed_settings = {
'theme': ['light', 'dark', 'auto'],
'language': ['en', 'es', 'fr', 'de'],
'notifications': [True, False],
'page_size': range(10, 101),
'timeout': range(30, 301)
}
validated = {}
for key, value in config.items():
if key in allowed_settings:
allowed_values = allowed_settings[key]
if isinstance(allowed_values, list) and value in allowed_values:
validated[key] = value
elif isinstance(allowed_values, range) and value in allowed_values:
validated[key] = value
return validated
def apply_validated_config(config):
# Safe configuration application
for key, value in config.items():
# Use Django settings or model updates
if key == 'theme':
# Update user theme preference
pass
elif key == 'language':
# Update user language preference
pass
# Apply other safe configurations
# Safe: Database operations
def safe_execute_db_operation(request):
operation = request.POST.get('operation', '')
model_name = request.POST.get('model', '')
filters = json.loads(request.POST.get('filters', '{}'))
try:
# Validate inputs
validated_operation = validate_db_operation(operation, model_name, filters)
# Execute safe database operation
result = execute_validated_db_operation(validated_operation)
return JsonResponse({'result': result})
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
def validate_db_operation(operation, model_name, filters):
# Validate operation
allowed_operations = ['count', 'exists', 'list']
if operation not in allowed_operations:
raise ValidationError('Operation not allowed')
# Validate model
allowed_models = ['User', 'Post', 'Comment']
if model_name not in allowed_models:
raise ValidationError('Model not allowed')
# Validate filters
allowed_filter_fields = {
'User': ['username', 'is_active', 'date_joined'],
'Post': ['title', 'status', 'created_at'],
'Comment': ['approved', 'created_at']
}
validated_filters = {}
model_fields = allowed_filter_fields.get(model_name, [])
for field, value in filters.items():
if field in model_fields:
validated_filters[field] = value
return {
'operation': operation,
'model': model_name,
'filters': validated_filters
}
def execute_validated_db_operation(operation_data):
operation = operation_data['operation']
model_name = operation_data['model']
filters = operation_data['filters']
# Map model names to actual models
model_map = {
'User': User,
'Post': Post,
'Comment': Comment
}
model_class = model_map[model_name]
queryset = model_class.objects.filter(**filters)
if operation == 'count':
return queryset.count()
elif operation == 'exists':
return queryset.exists()
elif operation == 'list':
# Return limited data
return [{'id': obj.id} for obj in queryset[:10]]
# Safe: Template processing
def safe_process_template(request):
template_name = request.POST.get('template', '')
context_data = request.POST.get('context', '{}')
try:
# Validate template
if template_name not in get_allowed_templates():
raise ValidationError('Template not allowed')
# Validate context
context = json.loads(context_data)
validated_context = validate_template_context(context)
# Safe: Django template rendering
from django.template.loader import render_to_string
rendered = render_to_string(template_name, validated_context)
return JsonResponse({'rendered': rendered})
except (json.JSONDecodeError, ValidationError) as e:
return JsonResponse({'error': 'Template processing failed'}, status=400)
def get_allowed_templates():
return [
'user/profile.html',
'notifications/email.html',
'reports/summary.html'
]
def validate_template_context(context):
# Validate and sanitize template context
allowed_keys = ['user_name', 'title', 'content', 'date']
validated = {}
for key, value in context.items():
if key in allowed_keys and isinstance(value, (str, int, float, bool)):
if isinstance(value, str):
validated[key] = value[:200] # Limit string length
else:
validated[key] = value
return validated