Flask-SecurityTxt
Flask-SecurityTxt is a simple extension for Flask that makes it easy to add a security.txt file to your website. This file, as specified by RFC 9116 and described at securitytxt.org, is used to provide information to security researchers about how to report vulnerabilities in your website.
The Flask-SecurityTxt logo makes use of the
cloud-lock-outlineicon created by Michael Richins as part of the Material Design Icons (MDI) library and published through Pictogrammers under the Apache License 2.0.
Installation
You can install Flask-SecurityTxt using pip:
pip install Flask-SecurityTxt
Signing the security.txt with a PGP key requires pgpy, which is not installed
by default:
pip install Flask-SecurityTxt[sign]
If Flask-Babel is used to detect the value of the Preferred-Languages
field, it can be installed through the babel extra in the same way:
pip install Flask-SecurityTxt[babel]
Usage
from flask import Flask
from flask_security_txt import SecurityTxt
app = Flask(__name__)
security_txt = SecurityTxt(app)
Under the application factory pattern, the application is passed to
init_app() instead. A single SecurityTxt instance can initialize several
applications, each with its own configuration:
security_txt = SecurityTxt()
def create_app():
app = Flask(__name__)
security_txt.init_app(app)
return app
You can also customize the contents of the security.txt file by providing the following settings in the configuration file:
| Property | Type | Default | Description |
|---|---|---|---|
SECURITY_TXT_ENDPOINT |
str |
"security_txt" |
The name by which the end-point will be known to the Flask-app. |
WELL_KNOWN_DIR |
str |
".well-known" |
The name of the directory that will contain the security.txt file. The key is deliberately not prefixed, so that every extension serving from this directory can share one location. |
SECURITY_TXT_FILE_NAME |
str |
"security.txt" |
The name of the security.txt file. |
SECURITY_TXT_SIGN_KEY |
str |
None |
The path to a file containing a PGP key used for signing the security.txt file. Requires the sign extra. The key must be a private key, and is read and verified when the application is initialized. |
SECURITY_TXT_SIGN_KEY_PASSPHRASE |
str |
None |
The passphrase of the key in SECURITY_TXT_SIGN_KEY. Required if, and only if, that key is passphrase-protected. |
SECURITY_TXT_CONTACT |
str Iterable |
None |
The value of the Contact field. An Iterable type value will result in multiple Contact fields. If None, the value is automatically generated from SECURITY_TXT_CONTACT_MAILBOX. |
SECURITY_TXT_CONTACT_MAILBOX |
str |
"security" |
The local part of the automatically generated Contact email address. Only used if SECURITY_TXT_CONTACT is None. |
SECURITY_TXT_EXPIRES |
str datetime |
None |
The value of the Expires field. A str type value is parsed into a datetime using dateutil; an unparseable string raises a ValueError. A datetime type value is formatted as an RFC 3339 timestamp with microseconds stripped; a value without a timezone is assumed to be in UTC, as RFC 9116 requires an offset. If None, the value is automatically generated using SECURITY_TXT_EXPIRES_OFFSET. |
SECURITY_TXT_EXPIRES_OFFSET |
timedelta dict tuple |
{"weeks": 1} |
The offset applied to datetime.now() to automatically generate the Expires field value. A dict is unpacked and passed to the timedelta constructor as keyword arguments; a tuple is passed as positional arguments, which are interpreted as days, seconds, microseconds, milliseconds, minutes, hours, and weeks. |
SECURITY_TXT_ENCRYPTION |
str Iterable |
None |
The value of the Encryption field. An Iterable type value will result in multiple Encryption fields. A value of None will omit the field entirely. |
SECURITY_TXT_ACKNOWLEDGMENTS |
str Iterable |
None |
The value of the Acknowledgments field. An Iterable type value will result in multiple Acknowledgments fields. A value of None will omit the field entirely. |
SECURITY_TXT_PREFERRED_LANGUAGES |
str list tuple |
None |
The value of the Preferred-Languages field, which RFC 9116 permits only once; a list or tuple type value will therefore result in a single comma-separated field. If None, the value falls back to the translations listed by the Flask-Babel extension if it is loaded, or "en" otherwise. |
SECURITY_TXT_CANONICAL |
str Iterable |
None |
The value of the Canonical field. An Iterable type value will result in multiple Canonical fields. If None, the value is resolved from the endpoint name in SECURITY_TXT_ENDPOINT using url_for, which is the location the security.txt is served from. |
SECURITY_TXT_POLICY |
str Iterable |
None |
The value of the Policy field. An Iterable type value will result in multiple Policy fields. A value of None will omit the field entirely. |
SECURITY_TXT_HIRING |
str Iterable |
None |
The value of the Hiring field. An Iterable type value will result in multiple Hiring fields. A value of None will omit the field entirely. |
SECURITY_TXT_FIELD_CASE |
str |
"standard" |
Controls the casing of field names in the output. Accepted values are "standard" (title case, e.g. Contact:), "lower" (e.g. contact:), and "upper" (e.g. CONTACT:). |
SECURITY_TXT_HEADER |
str |
A comment block prepended to the security.txt. The default header includes the Flask-SecurityTxt version and project links. The placeholder {version} is replaced with the installed version. Set to None to omit the header entirely. |
|
SECURITY_TXT_FOOTER |
str |
None |
A comment block appended to the security.txt. The placeholder {version} is replaced with the installed version. A value of None will omit the footer entirely. |
SECURITY_TXT_COMMENT_LINE_PREFIX |
str |
"# " |
The prefix added to every line of the header, the footer, and each field comment. Trailing whitespace is stripped, so that blank lines within a comment do not carry any. |
Every field that holds a URL accepts, besides a full URL using one of the
schemes allowed for that field, the name of a file in the application's static
folder or the name of an end-point that can be resolved by the application.
Both are rendered as external https: URLs. A value that is none of the three
raises a ValueError.
These settings can also be passed to the constructor, as a dict whose keys
are the property names without the SECURITY_TXT_ prefix and in lower case.
They then serve as defaults, which the application configuration still
overrides. An unknown key raises a ValueError, so that a typo is not silently
ignored:
security_txt = SecurityTxt(app, config={
"contact_mailbox": "abuse",
"expires_offset": {"days": 90},
})
Configuring Comments
For each field, a comment can be added on the line immediately preceding it by
setting a config key of the form SECURITY_TXT_<FIELD>_COMMENT, where
<FIELD> is the upper-case field name with any hyphen replaced by an
underscore (e.g. SECURITY_TXT_CONTACT_COMMENT,
SECURITY_TXT_PREFERRED_LANGUAGES_COMMENT). Each line of the comment is
prefixed with SECURITY_TXT_COMMENT_LINE_PREFIX automatically, and the comment
is preceded by an empty line. The comment of which a field is not rendered, is
not rendered either.
Configuring Contact Details
The Contact field of the security.txt file can be configured with one of
two different ways. First of all, the whole value string can be defined
using the SECURITY_TXT_CONTACT property. This takes precedence over the
alternative method, which uses the SECURITY_TXT_CONTACT_MAILBOX property.
The value of this property is combined with the domain name in SERVER_NAME,
or with that of the current request if SERVER_NAME is not configured. The
latter method is less reliable, as the client determines the host of a
request; as such, the prior method is preferred if possible. By default, the
contact is set to be "security@<domain>", with the domain name being
provided by Flask.
Example
A security.txt file will be available in your website's .well-known
directory, with the following contents:
#
# GENERATED BY FLASK-SECURITYTXT 1.4.0
#
# Flask-SecurityTxt has been developed by M.P. van de Weerd for
# Parcifal Programmatics under the AGPLv3 licence.
#
# https://pypi.org/project/Flask-SecurityTxt/
# https://scm.parcifal.dev/parcifal/flask-security-txt
#
# https://www.van-de-weerd.net/
# https://www.parcifal.dev/
#
Contact: mailto:security@example.com
Expires: 2026-10-12T13:52:49+00:00
Preferred-Languages: en
Canonical: https://example.com/.well-known/security.txt
Contributing
Found a bug? Have a suggestion? Open an issue or submit a merge request at the Forgejo repository. All contributions are welcome.
Metadata
Release files for Flask-SecurityTxt 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flask_securitytxt-1.4.0.tar.gz | 32.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flask_securitytxt-1.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 59.0 kB
Release files / flask_securitytxt-1.4.0.tar.gz
| Download URL | flask_securitytxt-1.4.0.tar.gz |
|---|---|
| Size | 32.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
046ec636df2a7c0a95dc6b922f525cca6e133e6c1f54308133f6fd6ceb285080
|
|
BLAKE2b-256 checksum How to use checksums |
df7896cd5979cb325040edb09c47d7da793d9464a6e8353ffcba58598a46fefd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / flask_securitytxt-1.4.0-py3-none-any.whl
| Download URL | flask_securitytxt-1.4.0-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9aec16b839eedd6e9f7df233d448b43446052feebc1bb18bd1a634da5fd4e489
|
|
BLAKE2b-256 checksum How to use checksums |
44e38a38dd52eec84bec3a8e64072a7cfa4f353c4d72d328bc74cfafc38c3bce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|