from flask import Flask, request, render_template
from jinja2 import Environment, FileSystemLoader, select_autoescape
from markupsafe import escape, Markup
import bleach
app = Flask(__name__)
# Safe: Autoescaping enabled
template_env = Environment(
loader=FileSystemLoader('templates'),
autoescape=select_autoescape(['html', 'xml']) # Safe!
)
@app.route('/profile')
def user_profile():
name = request.args.get('name', 'Guest')
bio = request.args.get('bio', '')
# Safe: Use Flask's render_template (auto-escapes by default)
return render_template('profile.html', name=name, bio=bio)
@app.route('/comment')
def show_comment():
comment = request.args.get('comment', '')
# Safe: Template with autoescaping
template = template_env.from_string(
'<div class="comment">{{ comment }}</div>'
)
return template.render(comment=comment) # Auto-escaped
@app.route('/dynamic')
def dynamic_content():
content = request.args.get('content', '')
# Safe: Autoescaping enabled environment
html = template_env.from_string('''
<html>
<body>
<h1>Dynamic Content</h1>
<div>{{ user_content }}</div>
</body>
</html>
''').render(user_content=content) # Auto-escaped
return html
@app.route('/rich-content')
def rich_content():
content = request.args.get('content', '')
# Safe: Sanitize HTML for rich content
allowed_tags = ['b', 'i', 'em', 'strong', 'p', 'br', 'ul', 'ol', 'li']
allowed_attrs = {}
clean_content = bleach.clean(content,
tags=allowed_tags,
attributes=allowed_attrs)
# Mark as safe after sanitization
safe_content = Markup(clean_content)
return template_env.from_string(
'<div class="rich-content">{{ content }}</div>'
).render(content=safe_content)
# templates/profile.html (safe with autoescaping):
# <h1>Welcome {{ name }}!</h1> <!-- Auto-escaped -->
# <p>Bio: {{ bio }}</p> <!-- Auto-escaped -->
#
# For trusted HTML (use carefully):
# <div class="trusted">{{ trusted_html|safe }}</div>
# Configuration validation
def validate_jinja_config():
"""Ensure Jinja2 is configured securely"""
if not template_env.autoescape:
raise ValueError("Jinja2 autoescaping must be enabled!")
print("✓ Jinja2 autoescaping is properly configured")
if __name__ == '__main__':
validate_jinja_config()
app.run(debug=False) # Never run debug=True in production