TypeError / secure

Lightweight modern Python library to add security headers (CSP, HSTS, etc.) to Django, Flask, FastAPI, and more. Secure defaults or fully customizable.
MIT License
880 stars 27 forks source link
content-security-policy django fastapi flask headers headers-security http-headers python python-security referrer-policy secure-headers security security-headers strict-transport-security web-security

secure.py

A simple, yet powerful way to secure your Python web applications across multiple frameworks.

PyPI Version Python Versions Ruff Downloads License GitHub Stars

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?


Supported Frameworks

secure.py supports the following Python web frameworks:

Framework Documentation
aiohttp Integration Guide
Bottle Integration Guide
CherryPy Integration Guide
Django Integration Guide
Falcon Integration Guide
FastAPI Integration Guide
Flask Integration Guide
Masonite Integration Guide
Morepath Integration Guide
Pyramid Integration Guide
Quart Integration Guide
Responder Integration Guide
Sanic Integration Guide
Starlette Integration Guide
Tornado Integration Guide
TurboGears Integration Guide

Features


Requirements


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

# Initialize secure headers with default settings
secure_headers = secure.Secure.with_default_headers()

# Apply the headers to your framework response object
secure_headers.set_headers(response)

Asynchronous Usage

For frameworks like FastAPI and Starlette that support asynchronous operations, use the async method:

import secure

# Initialize secure headers with default settings
secure_headers = secure.Secure.with_default_headers()

# Apply the headers asynchronously to your framework response object
await secure_headers.set_headers_async(response)

Example Usage

import secure

# Create a Secure instance with default headers
secure_headers = secure.Secure.with_default_headers()

# Apply default secure headers to a response object
secure_headers.set_headers(response)

Default Secure Headers

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

# Build a custom CSP policy
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")
)

# Apply it to secure headers
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

# Build a custom Permissions Policy
permissions = (
    secure.PermissionsPolicy()
    .geolocation("'self'")
    .camera("'none'")
    .microphone("'none'")
)

# Apply it to secure headers
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.