secure.py
A simple, yet powerful way to secure your Python web applications across multiple frameworks.
Introduction
In today's web landscape, security is paramount. secure.py is a lightweight Python library designed to effortlessly add security headers to your web applications, protecting them from common vulnerabilities. Whether you're using Django, Flask, FastAPI, or any other popular framework, secure.py
provides a unified API to enhance your application's security posture.
Why Use secure.py?
- 🔒 Apply Essential Security Headers: Implement headers like CSP, HSTS, and more with minimal effort.
- 🛠️ Consistent API Across Frameworks: A unified approach for different web frameworks.
- ⚙️ Customizable with Secure Defaults: Start secure out-of-the-box and customize as needed.
- 🚀 Easy Integration: Compatible with Python's most-used frameworks.
- 🐍 Modern Pythonic Design: Leverages Python 3.10+ features for cleaner and more efficient code.
Supported Frameworks
secure.py supports the following Python web frameworks:
Features
- 🔒 Secure Headers: Automatically apply headers like
Strict-Transport-Security
, X-Frame-Options
, and more. - 🛠️ Customizable Policies: Flexibly build your own security policies using method chaining.
- 🌐 Framework Integration: Compatible with various frameworks, ensuring cross-compatibility.
- 🚀 No External Dependencies: Lightweight and easy to include in any project.
- 🧩 Easy to Use: Integrate security headers in just a few lines of code.
- ⚡ Asynchronous Support: Async support for modern frameworks like FastAPI and Starlette.
- 📝 Enhanced Type Hinting: Complete type annotations for better developer experience.
- 📚 Attribution to Trusted Sources: Implements recommendations from MDN and OWASP.
Requirements
-
Python 3.10 or higher
This library leverages modern Python features introduced in Python 3.10 and 3.11, such as:
- Union Type Operator (
|
): Simplifies type annotations. - Structural Pattern Matching (
match
statement): Enhances control flow. - Improved Type Hinting and Annotations: Provides better code clarity and maintenance.
cached_property
: Optimize memory usage and performance.
Note: If you're using an older version of Python (3.6 to 3.9), please use version 0.3.0 of this library, which maintains compatibility with those versions.
-
Dependencies
This library has no external dependencies outside of the Python Standard Library.
Installation
You can install secure.py using pip, pipenv, or poetry:
pip:
pip install secure
Pipenv:
pipenv install secure
Poetry:
poetry add secure
Getting Started
Once installed, you can quickly integrate secure.py
into your project:
Synchronous Usage
import secure
secure_headers = secure.Secure.with_default_headers()
secure_headers.set_headers(response)
Asynchronous Usage
For frameworks like FastAPI and Starlette that support asynchronous operations, use the async method:
import secure
secure_headers = secure.Secure.with_default_headers()
await secure_headers.set_headers_async(response)
Example Usage
import secure
secure_headers = secure.Secure.with_default_headers()
secure_headers.set_headers(response)
By default, secure.py
applies the following headers when using with_default_headers()
:
Cache-Control: no-store
Cross-Origin-Opener-Policy: same-origin
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'
Strict-Transport-Security: max-age=31536000
Permissions-Policy: geolocation=(), microphone=(), camera=()
Referrer-Policy: strict-origin-when-cross-origin
Server:
X-Content-Type-Options: nosniff
Policy Builders
secure.py
allows you to customize headers such as Content-Security-Policy and Permissions-Policy with ease:
Content-Security-Policy Example
import secure
csp = (
secure.ContentSecurityPolicy()
.default_src("'self'")
.script_src("'self'", "cdn.example.com")
.style_src("'unsafe-inline'")
.img_src("'self'", "images.example.com")
.connect_src("'self'", "api.example.com")
)
secure_headers = secure.Secure(csp=csp)
Resulting HTTP headers:
Content-Security-Policy: default-src 'self'; script-src 'self' cdn.example.com; style-src 'unsafe-inline'; img-src 'self' images.example.com; connect-src 'self' api.example.com
Permissions-Policy Example
import secure
permissions = (
secure.PermissionsPolicy()
.geolocation("'self'")
.camera("'none'")
.microphone("'none'")
)
secure_headers = secure.Secure(permissions=permissions)
Resulting HTTP headers:
Permissions-Policy: geolocation=('self'), camera=('none'), microphone=('none')
Framework Examples
FastAPI
from fastapi import FastAPI
from secure import Secure
app = FastAPI()
secure_headers = Secure.with_default_headers()
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
await secure_headers.set_headers_async(response)
return response
@app.get("/")
def read_root():
return {"Hello": "World"}
Flask
from flask import Flask, Response
from secure import Secure
app = Flask(__name__)
secure_headers = Secure.with_default_headers()
@app.after_request
def add_security_headers(response: Response):
secure_headers.set_headers(response)
return response
@app.route("/")
def home():
return "Hello, world"
if __name__ == "__main__":
app.run()
Documentation
For more details, including advanced configurations and integration examples, please visit the full documentation.
Attribution
This library implements security recommendations from trusted sources:
We have included attribution comments in the source code where appropriate.
Resources
License
This project is licensed under the terms of the MIT License.
Contributing
Contributions are welcome! If you'd like to contribute to secure.py
, please feel free to open an issue or submit a pull request on GitHub.
Changelog
For a detailed list of changes, please refer to the CHANGELOG.
Acknowledgements
We would like to thank the contributors of MDN Web Docs and OWASP Secure Headers Project for their invaluable resources and guidelines that help make the web a safer place.