Implementing security.txt.

A new standard has been proposed that will allow web sites to provide a way to communicate security-related issues. A “security.txt” file containing the relevant information should be placed in the “.well-known” directory of the web server.

The securitytxt.org website has a form that allows you to quickly generate the text to be included in the “security.txt” file.

Copy the text just generated and paste it into the appropriate security.txt file on your web sever.

To do this first go to the root directory of your webserver in our case “/var/www/virtual/example.com/htdocs”.

# cd /var/www/virtual/example.com/htdocs

Now create a new directory “.well-known”

# mkdir .well-known

In the newly created directory create the file “security.txt”.

# touch .well-known/security.txt

Change the owner of the new directory and file to the user assigned to the web server in our case “www-data”.

# chown -R www-data. .well-known/

Now open the file.

# vi .well-known/security.txt

And paste the text you have previously generated or add the information manually.

Contact: https://example.com/contact/
Expires: 2023-11-09T23:00:00.000Z

The minimum information you need to publish is “Contact” and ” Expires”. Make sure the expiration date is less than 1 year.

To fully comply with applicable standards, also add the “Canonical” parameter and digitally sign the file.

If you are working with virtual hosts it is recommended to generate a new key for each domain.

# gpg --gen-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Enter the domain after “Real name” when prompted.

Real name: example.com

Next enter “Email address” when prompted.

Email address: info@example.com

Enter “O” for okay to finish the process and create key

You selected this USER-ID:
    "example.com <info@example.com>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? O

Enter password (twice) when prompted.

Export the public key to a file we call gpg.asc and save it in the webroot.

# gpg --export -a --output ./gpg.asc info@example.com

Change the owner of the file to the user assigned to the web server in our case “www-data”.

# chown -R www-data. gpg.asc

For convenience, we now switch to the .well-known directory.

# cd .well-known/

We are going to make some preliminary changes to the security.txt file.

# vi security.txt
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Contact: https://example.com/contact/
Expires: 2024-02-12T23:00:00.000Z
Canonical: https://example.com/.well-known/security.txt
Encryption: https://example.com/gpg.asc

Note that for “Contact”, we refer to a contact form on the web site to avoid putting an email address in the file that is prone to email scraping.

Next create the digital signature.

# gpg -u info@example.com --output security.txt.sig --armor --detach-sig security.txt

And verify that the signature contains no errors.

# gpg --verify security.txt.sig security.txt

Should give you something like this :

gpg: Signature made Mon Jan 13 18:20:59 2023 CET
gpg:                using RSA key 2BEC533DA926C6EF98BCFA6F6WWE3DDC7133A75C
gpg:                issuer "info@example.com"
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   3  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: next trustdb check due at 2025-01-17
gpg: Good signature from "example.com <info@example.com>" [ultimate]

Finally, we need to add the signature to our security.txt file

# cat security.txt.sig >> security.txt

To verify that your security.txt meets all the requirements and the digital signature is valid you can run an online test at internet.nl