from flask import Flask, request
@app.route('/calculate')
def calculate():
# Vulnerable: eval() with user input allows arbitrary code execution
expression = request.args.get('expr')
try:
result = eval(expression) # DANGEROUS: RCE vulnerability
return f'Result: {result}'
except:
return 'Error in calculation', 400
@app.route('/config')
def update_config():
# Vulnerable: Using eval() to parse configuration
config_data = request.form.get('config')
try:
# Dangerous: eval() allows arbitrary code execution
config = eval(config_data) # Can execute malicious code
return f'Config updated: {config}'
except:
return 'Invalid config', 400
@app.route('/process')
def process_data():
# Vulnerable: Dynamic function execution
func_name = request.args.get('function')
args = request.args.get('args')
# Extremely dangerous: eval() with user-controlled function calls
code = f'{func_name}({args})'
result = eval(code) # Complete RCE vulnerability
return str(result)
from flask import Flask, request
import ast
import operator
import json
import re
# Safe operators for mathematical expressions
SAFE_OPERATORS = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
ast.Pow: operator.pow,
ast.USub: operator.neg,
ast.UAdd: operator.pos
}
def safe_eval_math(expression):
"""Safely evaluate mathematical expressions."""
try:
# Parse the expression into an AST
node = ast.parse(expression, mode='eval')
return eval_ast_node(node.body)
except (ValueError, TypeError, SyntaxError):
raise ValueError('Invalid mathematical expression')
def eval_ast_node(node):
"""Recursively evaluate AST nodes with only safe operations."""
if isinstance(node, ast.Constant): # Numbers
return node.value
elif isinstance(node, ast.BinOp): # Binary operations
left = eval_ast_node(node.left)
right = eval_ast_node(node.right)
if type(node.op) in SAFE_OPERATORS:
return SAFE_OPERATORS[type(node.op)](left, right)
else:
raise ValueError('Unsupported operation')
elif isinstance(node, ast.UnaryOp): # Unary operations
operand = eval_ast_node(node.operand)
if type(node.op) in SAFE_OPERATORS:
return SAFE_OPERATORS[type(node.op)](operand)
else:
raise ValueError('Unsupported unary operation')
else:
raise ValueError('Unsupported expression type')
@app.route('/calculate')
def calculate():
# Secure: Use safe mathematical expression evaluator
expression = request.args.get('expr', '')
# Validate expression format
if not re.match(r'^[0-9+\-*/()\. ]+$', expression):
return 'Invalid expression format', 400
try:
result = safe_eval_math(expression)
return f'Result: {result}'
except ValueError as e:
return f'Error: {str(e)}', 400
except ZeroDivisionError:
return 'Error: Division by zero', 400
@app.route('/config')
def update_config():
# Secure: Use JSON parsing instead of eval()
config_data = request.form.get('config', '{}')
try:
# Safe: JSON parsing instead of eval()
config = json.loads(config_data)
# Validate configuration structure
allowed_keys = ['theme', 'language', 'timeout']
if not isinstance(config, dict):
return 'Config must be a dictionary', 400
for key in config.keys():
if key not in allowed_keys:
return f'Invalid config key: {key}', 400
return f'Config updated: {config}'
except json.JSONDecodeError:
return 'Invalid JSON format', 400
@app.route('/process')
def process_data():
# Secure: Use allowlist of permitted functions
func_name = request.args.get('function', '')
args_str = request.args.get('args', '')
# Allowlist of safe functions
safe_functions = {
'upper': lambda x: x.upper() if isinstance(x, str) else '',
'lower': lambda x: x.lower() if isinstance(x, str) else '',
'length': lambda x: len(x) if isinstance(x, (str, list)) else 0,
'reverse': lambda x: x[::-1] if isinstance(x, (str, list)) else x
}
if func_name not in safe_functions:
return 'Function not allowed', 400
try:
# Safe: Parse arguments as JSON
args = json.loads(args_str) if args_str else ''
result = safe_functions[func_name](args)
return str(result)
except (json.JSONDecodeError, TypeError) as e:
return f'Error processing: {str(e)}', 400
# Alternative secure approach using ast.literal_eval for simple data
@app.route('/parse_data')
def parse_data():
# Secure: Use ast.literal_eval for safe literal evaluation
data = request.args.get('data', '')
try:
# Safe: Only evaluates literals (strings, numbers, tuples, lists, dicts, booleans, None)
parsed = ast.literal_eval(data)
return f'Parsed data: {parsed}'
except (ValueError, SyntaxError):
return 'Invalid data format', 400