# Vulnerable: eval() with format strings and user input
from django.http import JsonResponse
from django.views import View
from django.shortcuts import render
# Extremely dangerous: eval() with f-string
class DynamicCalculatorView(View):
def get(self, request):
var_name = request.GET.get('var', 'x')
var_value = request.GET.get('value', '0')
expression = request.GET.get('expr', 'x + 1')
try:
# CRITICAL: eval() with f-string containing user input
code = f"{var_name} = {var_value}; result = {expression}"
result = eval(code)
return JsonResponse({'result': result})
except Exception as e:
return JsonResponse({'error': str(e)})
# Another dangerous pattern with .format()
def process_user_formula(request):
formula_template = request.POST.get('template', '')
user_vars = request.POST.get('variables', {})
try:
# Dangerous: format() with user input in eval()
formatted_code = formula_template.format(**user_vars)
result = eval(formatted_code)
return JsonResponse({'result': result})
except Exception as e:
return JsonResponse({'error': str(e)})
# Template injection through eval
def render_dynamic_content(request):
template_str = request.POST.get('template', '')
context_vars = request.POST.get('context', {})
# Dangerous: eval() with formatted template
try:
# User can inject: {__import__('os').system('rm -rf /')}
rendered_template = template_str.format(**context_vars)
result = eval(f"f'{rendered_template}'")
return JsonResponse({'rendered': result})
except Exception as e:
return JsonResponse({'error': str(e)})
# Configuration processing with format strings
def update_dynamic_config(request):
config_template = request.POST.get('config_template', '')
config_values = request.POST.get('values', {})
try:
# Dangerous: eval() with formatted configuration
config_code = config_template.format(**config_values)
# Execute configuration code
exec(config_code)
return JsonResponse({'status': 'config_updated'})
except Exception as e:
return JsonResponse({'error': str(e)})
# Query generation with format strings
def dynamic_query_builder(request):
query_template = request.GET.get('query', '')
query_params = request.GET.get('params', {})
try:
# Dangerous: eval() for query building
query_code = query_template.format(**query_params)
# Execute query code
result = eval(query_code)
return JsonResponse({'data': list(result)})
except Exception as e:
return JsonResponse({'error': str(e)})
# Mathematical expression with variables
def evaluate_math_expression(request):
expression = request.POST.get('expression', '')
variables = request.POST.get('variables', {})
# Dangerous: format() + eval() combination
try:
# User input: expression = "{a} + {b}"
# variables = {"a": "__import__('os').system('whoami')", "b": "1"}
formatted_expr = expression.format(**variables)
result = eval(formatted_expr)
return JsonResponse({'result': result})
except Exception as e:
return JsonResponse({'error': str(e)})
# Secure: Safe alternatives to eval() with format strings
from django.http import JsonResponse
from django.views import View
from django.shortcuts import render
from django.template import Template, Context
from django.core.exceptions import ValidationError
import json
import re
import ast
import operator
# Safe: Structured calculator without eval()
class SafeDynamicCalculatorView(View):
def get(self, request):
var_name = request.GET.get('var', '')
var_value = request.GET.get('value', '')
operation = request.GET.get('operation', '')
operand = request.GET.get('operand', '')
try:
# Validate inputs
validated_data = self.validate_calculator_inputs(
var_name, var_value, operation, operand
)
# Safe calculation
result = self.safe_calculate(validated_data)
return JsonResponse({'result': result})
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
def validate_calculator_inputs(self, var_name, var_value, operation, operand):
# Validate variable name
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', var_name):
raise ValidationError('Invalid variable name')
# Validate numeric values
try:
value = float(var_value)
operand_val = float(operand)
except ValueError:
raise ValidationError('Invalid numeric values')
# Validate operation
allowed_operations = ['+', '-', '*', '/', '**']
if operation not in allowed_operations:
raise ValidationError('Operation not allowed')
return {
'var_name': var_name,
'value': value,
'operation': operation,
'operand': operand_val
}
def safe_calculate(self, data):
operations = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv,
'**': operator.pow
}
op_func = operations[data['operation']]
return op_func(data['value'], data['operand'])
# Safe: Template processing without eval()
def safe_process_user_formula(request):
try:
formula_data = json.loads(request.body)
# Validate structure
validated_data = validate_formula_data(formula_data)
# Safe processing
result = process_formula_safely(validated_data)
return JsonResponse({'result': result})
except (json.JSONDecodeError, ValidationError) as e:
return JsonResponse({'error': 'Invalid formula data'}, status=400)
def validate_formula_data(data):
required_fields = ['operation', 'operands']
if not all(field in data for field in required_fields):
raise ValidationError('Missing required fields')
# Validate operation
allowed_operations = ['add', 'subtract', 'multiply', 'divide']
if data['operation'] not in allowed_operations:
raise ValidationError('Operation not allowed')
# Validate operands
operands = data['operands']
if not isinstance(operands, list) or len(operands) < 2:
raise ValidationError('Invalid operands')
# Ensure all operands are numbers
validated_operands = []
for operand in operands:
try:
validated_operands.append(float(operand))
except (ValueError, TypeError):
raise ValidationError('All operands must be numbers')
return {
'operation': data['operation'],
'operands': validated_operands
}
def process_formula_safely(data):
operation = data['operation']
operands = data['operands']
if operation == 'add':
return sum(operands)
elif operation == 'subtract':
result = operands[0]
for operand in operands[1:]:
result -= operand
return result
elif operation == 'multiply':
result = 1
for operand in operands:
result *= operand
return result
elif operation == 'divide':
result = operands[0]
for operand in operands[1:]:
if operand == 0:
raise ValidationError('Division by zero')
result /= operand
return result
# Safe: Django template system for dynamic content
def safe_render_dynamic_content(request):
template_name = request.POST.get('template_name', '')
context_data = request.POST.get('context', '{}')
# Validate template name
allowed_templates = [
'user_greeting.txt',
'order_summary.txt',
'notification.txt'
]
if template_name not in allowed_templates:
return JsonResponse({'error': 'Template not allowed'}, status=400)
try:
# Safe: JSON deserialization
context = json.loads(context_data)
# Validate context
validated_context = validate_template_context(context)
# Safe: Django template system
from django.template.loader import get_template
template = get_template(template_name)
rendered = template.render(validated_context)
return JsonResponse({'rendered': rendered})
except (json.JSONDecodeError, ValidationError) as e:
return JsonResponse({'error': 'Template rendering failed'}, status=400)
def validate_template_context(context):
if not isinstance(context, dict):
raise ValidationError('Context must be a dictionary')
allowed_keys = {'user_name', 'order_id', 'amount', 'items', 'date'}
validated = {}
for key, value in context.items():
if key in allowed_keys:
if key == 'user_name' and isinstance(value, str):
validated[key] = value[:50] # Limit length
elif key == 'order_id' and isinstance(value, (str, int)):
validated[key] = str(value)[:20]
elif key == 'amount' and isinstance(value, (int, float)):
validated[key] = round(float(value), 2)
elif key == 'items' and isinstance(value, list):
validated[key] = value[:10] # Limit items
elif key == 'date' and isinstance(value, str):
# Simple date validation
if re.match(r'^\d{4}-\d{2}-\d{2}$', value):
validated[key] = value
return validated
# Safe: Configuration updates without eval()
def safe_update_dynamic_config(request):
try:
config_data = json.loads(request.body)
# Validate configuration
validated_config = validate_config_data(config_data)
# Apply configuration safely
apply_configuration(validated_config)
return JsonResponse({'status': 'config_updated'})
except (json.JSONDecodeError, ValidationError) as e:
return JsonResponse({'error': 'Configuration update failed'}, status=400)
def validate_config_data(data):
if not isinstance(data, dict):
raise ValidationError('Configuration must be a dictionary')
allowed_configs = {
'max_items': int,
'timeout': int,
'debug_mode': bool,
'allowed_domains': list
}
validated = {}
for key, value in data.items():
if key in allowed_configs:
expected_type = allowed_configs[key]
if isinstance(value, expected_type):
# Additional validation
if key == 'max_items' and 1 <= value <= 1000:
validated[key] = value
elif key == 'timeout' and 1 <= value <= 300:
validated[key] = value
elif key == 'debug_mode':
validated[key] = bool(value)
elif key == 'allowed_domains' and isinstance(value, list):
# Validate domain list
domains = []
for domain in value[:10]: # Limit domains
if isinstance(domain, str) and re.match(r'^[a-zA-Z0-9.-]+$', domain):
domains.append(domain)
validated[key] = domains
return validated
# Safe: Query building with ORM
def safe_dynamic_query_builder(request):
model_name = request.GET.get('model', '')
filter_field = request.GET.get('field', '')
filter_value = request.GET.get('value', '')
order_by = request.GET.get('order', '')
# Use allowlists for everything
allowed_models = {
'user': User,
'post': Post,
'comment': Comment
}
allowed_fields = {
'user': ['username', 'email', 'date_joined'],
'post': ['title', 'status', 'created_at'],
'comment': ['content', 'approved', 'created_at']
}
allowed_order_fields = {
'user': ['username', 'date_joined'],
'post': ['title', 'created_at'],
'comment': ['created_at']
}
# Validate inputs
if model_name not in allowed_models:
return JsonResponse({'error': 'Model not allowed'}, status=400)
if filter_field not in allowed_fields.get(model_name, []):
return JsonResponse({'error': 'Field not allowed'}, status=400)
if order_by and order_by not in allowed_order_fields.get(model_name, []):
return JsonResponse({'error': 'Order field not allowed'}, status=400)
try:
model_class = allowed_models[model_name]
# Safe: Django ORM query
queryset = model_class.objects.filter(**{filter_field: filter_value})
if order_by:
queryset = queryset.order_by(order_by)
# Limit results
results = queryset[:100]
# Serialize safely
data = []
for obj in results:
data.append({
'id': obj.id,
filter_field: getattr(obj, filter_field)
})
return JsonResponse({'data': data})
except Exception as e:
return JsonResponse({'error': 'Query failed'}, status=400)