Skip to main content

A lightweight package that adds optional security headers and cookie attributes for Python web frameworks.

Project description

Secure

Secure 🔒 is a lightweight package that adds optional security headers and cookie attributes for Python web frameworks.

Supported Python web frameworks:

aiohttp, Bottle, CherryPy, Falcon, hug, Pyramid, Quart, Responder, Sanic, Tornado

Please see flask-talisman for Flask support and django-security for Django support.

Install

pip:

$ pip install secure

Pipenv:

$ pipenv install secure

Headers

Security Headers are HTTP response headers that, when set, can enhance the security of your web application by enabling browser security policies.

Recommendations used by Secure 🔒 and more information regarding security headers can be found at the OWASP Secure Headers Project.

Server

Contain information about server software
Default Value: NULL (obfuscate server information)

Strict-Transport-Security (HSTS)

Ensure application communication is sent over HTTPS
Default Value: max-age=63072000; includeSubdomains

X-Frame-Options (XFO)

Disable framing from different origins (clickjacking defense)
Default Value: SAMEORIGIN

X-XSS-Protection

Enable browser cross-site scripting filters
Default Value: X-XSS-Protection", "1; mode=block

X-Content-Type-Options

Prevent MIME-sniffing
Default Value: nosniff

Content-Security-Policy (CSP)

Prevent cross-site injections
Default Value: script-src 'self'; object-src 'self' (not included by default)*

Referrer-Policy

Enable full referrer if same origin, remove path for cross origin and disable referrer in unsupported browsers
Default Value: no-referrer, strict-origin-when-cross-origin

Cache-control / Pragma

Prevent cacheable HTTPS response
Default Value: no-cache, no-store, must-revalidate / no-cache

*The Content-Security-Policy (CSP) header can break functionality and can (and should) be carefully constructed, use the csp=True option to enable default values.

Example

secure.SecureHeaders.framework(response)

Default HTTP response headers:

Server: NULL
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
Cache-control: no-cache, no-store, must-revalidate
Pragma: no-cache

Options

You can toggle the setting of headers with default values by passing True or False and override default values by passing a string to the following options:

  • server - set the Server header, e.g. Server=“Secure” (string / bool, default=True)
  • hsts - set the Strict-Transport-Security header (string / bool, default=True)
  • xfo - set the X-Frame-Options header (string / bool, default=True)
  • xss - set the X-XSS-Protection header (string / bool, default=True)
  • content - set the X-Content-Type-Options header (string / bool, default=True)
  • csp - set the Content-Security-Policy (string / bool, default=False) *
  • referrer - set the Referrer-Policy header (string / bool, default=True)
  • cache - set the Cache-control and Pragma headers (string / bool, default=True)

Example

secure.SecureHeaders.framework(response, hsts=False, csp=True, xfo="DENY")

Cookies

Path

The Path directive instructs the browser to only send the cookie if provided path exists in the URL.

Secure

The Secure flag instructs the browser to only send the cookie via HTTPS.

HttpOnly

The HttpOnly flag instructs the browser to not allow any client side code to access the cookie's contents.

SameSite

The SameSite flag directs the browser not to include cookies on certain cross-site requests. There are two values that can be set for the same-site attribute, lax or strict. The lax value allows the cookie to be sent via certain cross-site GET requests, but disallows the cookie on all POST requests. For example cookies are still sent on links <a href=“x”>, prerendering <link rel=“prerender” href=“x” and forms sent by GET requests <form-method=“get”..., but cookies will not be sent via POST requests <form-method=“post”..., images <img src=“x”> or iframes <iframe src=“x”>. The strict value prevents the cookie from being sent cross-site in any context. Strict offers greater security but may impede functionality. This approach makes authenticated CSRF attacks impossible with the strict flag and only possible via state changing GET requests with the lax flag.

Expires

The Expires attribute sets an expiration date for persistent cookies.

Example

secure.SecureCookie.framework(response, name="framework", value="ABC123")

Default Set-Cookie HTTP response header:

Set-Cookie: framework=ABC123; Path=/; secure; HttpOnly; SameSite=lax

Options

You can modify default cookie attribute values by passing the following options:

  • name - set the cookie name (string, No default value)
  • value - set the cookie value (string, No default value)
  • path - set the Path attribute, e.g.path=“/secure” (string, default="/")
  • secure - set the Secure flag (bool, default=True)
  • httponly - set the HttpOnly flag (bool, default=True)
  • samesite - set the SameSite attribute, e.g. samesite=“strict” (bool / string, options: "lax", "strict" or False, default="lax")
  • expires - set the Expires attribute with the cookie expiration in hours, e.g.expires=1 (number / bool, default=False)

Example

secure.SecureCookie.framework(
        response,
        name="framework",
        value="ABC123",
        samesite=False,
        path="/secure",
        expires=24,
    )

Supported Frameworks

aiohttp

Headers

secure.SecureHeaders.aiohttp(resp)

Example
from aiohttp import web
from aiohttp.web import middleware
from secure import SecureHeaders

. . . 

@middleware
async def set_secure_headers(request, handler):
    resp = await handler(request)
    SecureHeaders.aiohttp(resp)
    return resp

. . . 

app = web.Application(middlewares=[set_secure_headers])

. . . 

Cookies

secure.SecureCookie.aiohttp(resp, name="aiohttp", value="ABC123")
Example
from aiohttp import web
from secure import SecureCookie

. . . 

@routes.get("/secure")
async def set_secure_cookie(request):
    resp = web.Response(text="Secure")
    SecureCookie.aiohttp(resp, name="aiohttp", value="ABC123")
    return resp

. . . 

Bottle

Headers

secure.SecureHeaders.bottle(response)

Example
from bottle import route, run, response, hook
from secure import SecureHeaders

. . . 

@hook("after_request")
def set_secure_headers():
    SecureHeaders.bottle(response)

. . . 

Cookies

secure.SecureCookie.bottle(response, name="bottle", value="ABC123")
Example
from bottle import route, run, response, hook
from secure import SecureCookie

. . . 

@route("/secure")
def set_secure_cookie():
    SecureCookie.bottle(response, name="bottle", value="ABC123")
    return "Secure"

. . . 

CherryPy

Headers

'tools.response_headers.headers': secure.SecureHeaders.cherrypy()

Example

CherryPy Application Configuration:

import cherrypy
from secure import SecureHeaders

. . . 

config = {
    '/': {
        'tools.response_headers.on': True,
        'tools.response_headers.headers': SecureHeaders.cherrypy(),
    }
}

. . . 

Cookies

response_headers = cherrypy.response.headers
secure.SecureCookie.cherrypy(response_headers, name="cherrypy", value="ABC123")
Example
import cherrypy
from secure import SecureCookie

. . . 

class SetSecureCookie(object):
    @cherrypy.expose
    def set_secure_cookie(self):
        response_headers = cherrypy.response.headers
        SecureCookie.cherrypy(response_headers, name="cherrypy", value="ABC123")
        return "Secure"

. . . 

Falcon

Headers

secure.SecureHeaders.falcon(resp)

Example
import falcon
from secure import SecureHeaders

. . . 

class SetSecureHeaders(object):
    def process_request(self, req, resp):
        SecureHeaders.falcon(resp)

. . . 

app = api = falcon.API(middleware=[SetSecureHeaders()])

. . . 

Cookies

secure.SecureCookie.falcon(resp, name="falcon", value="ABC123")
Example
import falcon
from secure import SecureCookie

. . . 

class SetSecureCookie(object):
    def on_get(self, req, resp):
        resp.body = "Secure"
        SecureCookie.falcon(resp, name="falcon", value="ABC123")

. . . 

hug

Headers

secure.SecureHeaders.hug(response)

Example
import hug
from secure import SecureHeaders

. . . 

@hug.response_middleware()
def set_secure_headers(request, response, resource):
      SecureHeaders.hug(response)

. . . 

Cookies

secure.SecureCookie.hug(response, name="hug", value="ABC123")
Example
import hug
from secure import SecureCookie

. . . 

@hug.get('/secure')
def set_secure_cookie(response=None):
    SecureCookie.hug(response, name="hug", value="ABC123")
    return "Secure"

. . . 

Pyramid

Headers

Pyramid Tween:

def set_secure_headers(handler, registry):
    def tween(request):
        response = handler(request)
        secure.SecureHeaders.pyramid(response)
        return response
Example
from pyramid.config import Configurator
from pyramid.response import Response
from secure import SecureHeaders

. . . 

def set_secure_headers(handler, registry):
    def tween(request):
        response = handler(request)
        SecureHeaders.pyramid(response)
        return response

    return tween

. . . 

config.add_tween(".set_secure_headers")

. . . 

Cookies

response = Response("Secure")
secure.SecureCookie.pyramid(response, name="pyramid", value="ABC123")
Example
from pyramid.config import Configurator
from pyramid.response import Response
from secure import SecureCookie

. . . 

def set_secure_cookie(request):
    response = Response("Secure")
    SecureCookie.pyramid(response, name="pyramid", value="ABC123")
    return response

. . . 

Responder

Headers

secure.SecureHeaders.responder(resp)

Example
import responder
from secure import SecureHeaders

api = responder.API()

. . . 

@api.route(before_request=True)
def set_secure_headers(req, resp):
    SecureHeaders.responder(resp)

. . . 

You should use Responder's built in HSTS and pass the hsts=False option.

Cookies

secure.SecureCookie.responder(resp, name="reponder", value="ABC123")
Example
import responder
from secure import SecureCookie

api = responder.API(cors=True)

. . . 

@api.route("/secure")
async def set_secure_cookie(req, resp):
    resp.text = "Secure"
    SecureCookie.responder(resp, name="reponder", value="ABC123")

. . . 

Quart

Headers

secure.SecureHeaders.quart(response)

Example
from quart import Quart, Response
from secure import SecureHeaders, SecureCookie

app = Quart(__name__)

. . . 

@app.after_request
async def set_secure_headers(response):
    SecureHeaders.quart(response)
    return response

. . . 

Cookies

secure.SecureCookie.quart(resp, name="quart", value="ABC123")
Example
from quart import Quart, Response
from secure import SecureHeaders, SecureCookie

app = Quart(__name__)

. . . 

@app.route('/secure')
async def set_secure_cookie():
    resp = Response("Secure")
    SecureCookie.quart(resp, name="quart", value="ABC123")
    return resp

. . . 

Sanic

Headers

secure.SecureHeaders.sanic(response)

Example
from sanic import Sanic
from secure import SecureHeaders

app = Sanic()

. . . 

@app.middleware('response')
async def set_secure_headers(request, response):
    SecureHeaders.sanic(response)

. . . 

Cookies

secure.SecureCookie.sanic(response, name="sanic", value="ABC123")
Example
from sanic import Sanic
from sanic.response import text
from secure import SecureCookie

app = Sanic()

. . . 

@app.route("/secure")
async def set_secure_cookie(request):
    response = text("Secure")
    SecureCookie.sanic(response, name="sanic", value="ABC123")
    return response

. . . 

To set Cross Origin Resource Sharing (CORS) headers, please see sanic-cors.

Tornado

Headers

secure.SecureHeaders.tornado(self)

Example
import tornado.ioloop
import tornado.web
from secure import SecureHeaders

. . . 

class BaseHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        SecureHeaders.tornado(self)

. . . 

Cookies

secure.SecureCookie.tornado(self, name="tornado", value="ABC123")
Example
import tornado.ioloop
import tornado.web
from secure import SecureCookie

. . . 

class SetSecureCookie(BaseHandler):
    def get(self):
        SecureCookie.tornado(self, name="tornado", value="ABC123")
        self.write("Secure")

. . . 

Attribution/References

Frameworks

  • aiohttp - Asynchronous HTTP client/server framework for asyncio and Python
  • Bottle - A fast and simple micro-framework for python web-applications.
  • CherryPy - A pythonic, object-oriented HTTP framework.
  • Falcon - A bare-metal Python web API framework for building high-performance microservices, app backends, and higher-level frameworks.
  • hug - Embrace the APIs of the future. Hug aims to make developing APIs as simple as possible, but no simpler.
  • Pyramid - A Python web framework
  • Quart - A Python ASGI web microframework.
  • Sanic - An Async Python 3.5+ web server that's written to go fast
  • Responder - A familiar HTTP Service Framework
  • Tornado - A Python web framework and asynchronous networking library, originally developed at FriendFeed.

Resources

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

secure-0.1.6.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

secure-0.1.6-py2-none-any.whl (8.9 kB view details)

Uploaded Python 2

File details

Details for the file secure-0.1.6.tar.gz.

File metadata

  • Download URL: secure-0.1.6.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

File hashes

Hashes for secure-0.1.6.tar.gz
Algorithm Hash digest
SHA256 6241419bfb51e27cae4e82ed5cb9c4edebecbc19ec808bf05e2be8eb55e41fc3
MD5 7231e82eb5cca6b10f8b0b810fc61a41
BLAKE2b-256 6eb804961fee08977a1918698bbee1c262c720f013431d19bf8852110f9c9559

See more details on using hashes here.

File details

Details for the file secure-0.1.6-py2-none-any.whl.

File metadata

  • Download URL: secure-0.1.6-py2-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

File hashes

Hashes for secure-0.1.6-py2-none-any.whl
Algorithm Hash digest
SHA256 06e433ef8168eedbdce747352b181a52a69c9ba61c268c6f220c2ed5633ae94c
MD5 bd171d374f8b9fb7d4c49668f068cd55
BLAKE2b-256 d7c5ffc12251545b6dd77cb929d6ee7b416317584519d4ba329e96800f8e68b3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page