Essential security utilities for Flask applications
Project description
Flask-Security-Headers
Essential security utilities for Flask applications - Prevent common vulnerabilities like open redirects, XSS attacks, and weak passwords with battle-tested helper functions.
Why Flask-Security-Headers?
Security shouldn't be an afterthought. This package provides production-ready security utilities that are:
- ✅ Battle-tested in production at WallMarkets
- ✅ Zero dependencies beyond Flask
- ✅ Easy to integrate - just import and use
- ✅ Well-documented with real-world examples
Features
🛡️ Open Redirect Prevention
Validate URLs before redirecting to prevent phishing attacks. Ensures redirects only go to your domain.
🔐 Password Strength Validation
Enforce strong passwords with customizable requirements:
- Minimum 8 characters
- Uppercase and lowercase letters
- Numbers and special characters
- Clear error messages for users
⏰ Fresh Login Requirement
Require recent authentication for sensitive operations (password changes, payment methods, etc.)
📁 Filename Sanitization
Prevent path traversal attacks by sanitizing uploaded filenames
🌐 Proxy-Aware IP Detection
Get the real client IP address, even behind proxies and load balancers
🔍 XSS Content Detection
Check user-submitted content for suspicious patterns before storing
Installation
pip install flask-security-headers
Quick Start
pip install flask-security-headers
Usage Examples
1. Safe URL Validation (Prevent Open Redirects)
from flask import redirect, request
from flask_security_headers import is_safe_url
@app.route('/redirect')
def safe_redirect():
target = request.args.get('next', '/')
if is_safe_url(target):
return redirect(target)
return redirect('/')
2. Require Fresh Login for Sensitive Operations
from flask_security_headers import require_fresh_login
@app.route('/settings/password', methods=['POST'])
@require_fresh_login(timeout_minutes=30)
def change_password():
# User must have logged in within last 30 minutes
pass
3. Password Strength Validation
from flask_security_headers import validate_password_strength
valid, msg = validate_password_strength(password)
if not valid:
return {'error': msg}, 400
4. Filename Sanitization (Prevent Path Traversal)
from flask_security_headers import sanitize_filename
filename = sanitize_filename(request.files['file'].filename)
# Safe to use in file paths
5. Get Client IP (Proxy-Aware)
from flask_security_headers import get_client_ip
@app.route('/api/endpoint')
def endpoint():
client_ip = get_client_ip()
# Works correctly behind proxies, load balancers, CDNs
app.logger.info(f"Request from {client_ip}")
6. Content Security Check
from flask_security_headers import check_content_security
@app.route('/comment', methods=['POST'])
def post_comment():
content = request.form['comment']
is_safe, message = check_content_security(content)
if not is_safe:
return {'error': f'Suspicious content detected: {message}'}, 400
# Safe to store
Real-World Use Cases
E-commerce Platform
# Secure password reset flow
@app.route('/reset-password/<token>', methods=['POST'])
def reset_password(token):
new_password = request.form['password']
# Validate password strength
valid, msg = validate_password_strength(new_password)
if not valid:
flash(msg, 'error')
return redirect(url_for('reset_password', token=token))
# Update password...
# Safe redirect
next_url = request.args.get('next', '/')
if is_safe_url(next_url):
return redirect(next_url)
return redirect('/')
Admin Panel
# Require fresh login for critical operations
@app.route('/admin/delete-user/<int:user_id>', methods=['POST'])
@login_required
@require_fresh_login(timeout_minutes=15)
def delete_user(user_id):
# User must have logged in within last 15 minutes
# Prevents session hijacking from causing damage
user = User.query.get_or_404(user_id)
db.session.delete(user)
db.session.commit()
return redirect(url_for('admin.users'))
File Upload Service
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['document']
# Sanitize filename to prevent path traversal
safe_filename = sanitize_filename(file.filename)
# "../../../etc/passwd" becomes "etc_passwd"
file.save(os.path.join(app.config['UPLOAD_FOLDER'], safe_filename))
API Reference
is_safe_url(target: str) -> bool
Validates if a URL is safe for redirect (same domain).
validate_password_strength(password: str) -> Tuple[bool, Optional[str]]
Returns (True, None) if valid, or (False, error_message) if invalid.
require_fresh_login(timeout_minutes: int = 30)
Decorator that requires recent authentication.
sanitize_filename(filename: str) -> str
Removes dangerous characters and path components from filenames.
get_client_ip() -> str
Returns the real client IP, respecting proxy headers if configured.
check_content_security(content: str) -> Tuple[bool, str]
Checks content for suspicious patterns like script tags.
Configuration
# Enable proxy header trust (only if behind a trusted proxy!)
app.config['BEHIND_PROXY'] = True
# Customize password requirements (optional)
app.config['MIN_PASSWORD_LENGTH'] = 10
app.config['REQUIRE_SPECIAL_CHARS'] = True
Security Best Practices
- Always validate redirects - Use
is_safe_url()before anyredirect() - Enforce strong passwords - Use
validate_password_strength()on registration/password change - Require fresh login - Use
@require_fresh_login()for sensitive operations - Sanitize filenames - Always use
sanitize_filename()for user uploads - Log security events - Track failed validation attempts
Testing
pytest tests/
Production Usage
This package is used in production at:
- WallMarkets - Multi-vendor marketplace platform
- Handling thousands of daily requests
- Protecting sensitive user operations
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
Related Packages
- flask-ratelimit-simple - Rate limiting
- flask-supercache - Caching
- flask-querymonitor - Query optimization
Made with ❤️ by the WallMarkets team
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flask_security_headers-1.0.2.tar.gz.
File metadata
- Download URL: flask_security_headers-1.0.2.tar.gz
- Upload date:
- Size: 6.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f192290a06039c41d655b6fe4151175e7bc79a606f308799505bf777acc4ab1
|
|
| MD5 |
b7d9a3eb0a9f480379ce4f38103d901e
|
|
| BLAKE2b-256 |
ebd2c2805aef757c524b5a9dfe23f4626b5f910635946c2d26e732365e91d950
|
File details
Details for the file flask_security_headers-1.0.2-py3-none-any.whl.
File metadata
- Download URL: flask_security_headers-1.0.2-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee8000f1eaad223ab4dba2098a90348d1c0d4da1ced5cb882c9bbdacc74b8051
|
|
| MD5 |
72d3acd310729f5f60b72e954278d6e6
|
|
| BLAKE2b-256 |
23acf1db3b5c9d8287eb5dc66d6e60282a5a1b158f213ecec4f9e63e7dc54f24
|