security.txt to your site, with correct contact details inside the file, so that people reporting security issues won't have to guess where to send the reports to. Using a real example, I'll show you why having such file is a good idea.
Sometimes, people find security vulnerabilities, and they would like to report them so the vendor or the developer can fix them. That was the case for me in December 2017 as well.
On Saturday, December 16, I reported a Cross-Site Scripting (XSS) vulnerability on a well known site Alza.cz (also known as Alza.co.uk and Alzashop.com). They were echoing the current URL to the Not Found page without any sanitization, between
</script> tags, to an event parameter they send to Google Analytics for tracking. The code for
https://www.alza.cz/foo looks like this:
<script> ga('send', 'event', 'Error404', 'http://www.alza.cz/foo'); </script>
Then when you loaded
https://www.alza.cz/foo?');+alert(1);+// in your browser, an alert popped up:
<script> ga('send', 'event', 'Error404', 'https://www.alza.cz/foo?'); alert(1); //'); </script>
alert(1), so I've built a proof-of-concept demo. When a user would click the malicious link, the login window would show up and when the user would try to enter their login credentials or submit the form, they would receive a “phishing demo” message instead. No data would be submitted. I could change the
action attribute of the login form to submit the password to my server, but that was not the point of the demo.
The malicious demo link (could be shortened with a URL shortener):
At last, the warning message over the login form:
Reporting the issue
To report the problem I first had to find the right person to report it to. You don't want to report security issues to customer support, they wouldn't know what to do with it. After some googling I found Vladimír Dědek, the director of web & mobile development. But who's Vladimír? How does he react to reports like this? Will he understand the report at all? Some more google queries, and here I was, watching a video interview (in Czech) where Vladimír talks with Jirka Rostecký about development-related things and stuff. Vladimír was the guy I was looking for. I've sent him a short email with the issue description and got back to whatever I originally intended to do.
Vladimír's response arrived the next day (on Sunday!) morning. Alza has fixed the vulnerability in a few days, they handled the report nicely, emails were also nice, so thanks Alza! Their quick response was similar to that of DomainTools – they fixed a similar vulnerability on Friday before Christmas.
Guess what took the most time: find the bug, prepare the demo, or find someone to report the issue to?
Yeah, you're right, I burned most of the time by trying to find the right contact. Must be someone who will understand the issue, and not scramble their lawyers instead. Some time ago, when I found a leaked data from a Czech hosting company (in Czech) just by a lucky accident, it also took me quite a while to find the right contact. I even asked their customer support to provide a dedicated security email and their response was “there's none” and that I should just send the report unencrypted to their support email and they'll get back to me. I kind of understand why companies do it, on the other hand it might discourage someone and then they may do things they'll regret later on.
Look, I get it, you don't want your “About” or “Contacts” page to have “Report security issues here” link but how to tell the potential reporters where to report their findings? You probably don't want people to ask for security contact details on Twitter like me, when I wanted to report issues with AlwaysOnSSL certification authority (which ceased to exist shortly after publishing this article). Contacts in
whois listing are often private or it's not the right people for security matters.
Ed Foudil tried to tackle this. He has created a draft for security.txt (the full name is “A Method for Web Security Policies”, soon to be published as an RFC hopefully), which in short is a file called
security.txt with security contacts where to send your reports to.
security.txt file has to be at a predictable location, for web sites it's the
/.well-known/ directory. That directory is defined in RFC 5785 and serves as a base directory for “well known” locations. It's used by e.g. KeyBase and Let's Encrypt certification authority for domain ownership validation and some more. The path to my
security.txt file is https://www.michalspacek.com/.well-known/security.txt, and there's a recommended redirection in place for /security.txt.
The redirection target must be on the same domain, you can't redirect from https://www.example.com/security.txt to https://www.example.net/.well-known/security.txt and not even to a subdomain e.g. https://foo.www.example.com/.well-known/security.txt – only to https://www.example.com/.well-known/security.txt.
If you can't place the
security.txt file in the
/.well-known/ path or setup a redirect, you can place the file in the top-level path as a fallback option.
On internal hosts or file systems you can (and should) place the
security.txt directly in the root directory.
The file must be served over HTTPS, and HTTPS must be used in all the URLs inside the file, including but not limited to the following directives.
The file uses directives and values, each directive can only have one value (e.g. an address). You can add more identical directives but with different values, each on a separate line which must end either with
CRLF or just
LF characters. The file must contain at least one
Contact directive with an email address (don't forget the
mailto: scheme, e.g.
mailto:firstname.lastname@example.org), a phone number (with the
tel: scheme, e.g.
tel:+123456789), or a web page with more info. My
Contact directives look like this:
Contact: https://www.michalspacek.com/contact Contact: https://twitter.com/messages/compose?recipient_id=15823805 Contact: https://m.me/spaze
Encryption directive you can (and should) add a link to your PGP key which can be used to encrypt the report. My directive:
Policy directive, you can add a link to your security policy and/or disclosure policy.
If you have a “Hall of Fame” page listing people or companies that disclosed security issues and worked with you to fix them (like what T-Mobile CZ has), you can add a link to such page here. It doesn't need to be complicated, check what AlwaysOnSSL linked to in their
Hiring security professionals? Add a link to open positions or job description here.
A list of natural languages (language tags) that are preferred when submitting security reports:
Preferred-Languages: cs, en
Languages in the list must be interpreted as all being of equal priority, and if the directive is absent, reporters may assume (or may not) that English is the language to be used.
Canonical and digital signature
You can sign the contents of your
security.txt using a cleartext signature where the signature is part of the original file. You can create the signature by running
gpg --clear-sign security.txt and then renaming the signed file (
security.txt.asc) back. Don't forget to update the signature whenever you change the file, even in the slightest.
security.txt file can also contain the
Canonical directive (and if the file is signed it is even recommended) which points back to where the file is located:
And in case the file is signed, the location is also signed so it's clear where the file comes from.
Indicates the date and time using the RFC 3339 format, after which the data contained in the particular
security.txt file is considered stale for whatever reason (like organizational changes) and should not be used anymore.
The date can be as far in the future as you wish but it's recommended to be less than a year into the future. Not having a
security.txt file may be better than having stale or outdated information in such file. Please make sure the file is kept current.
Even if you're too lazy to do anything today, you can still at least add the file (provided you know where the security reports should be sent to) and you can tick off the task “improve relationship with a security community and make reporting security issues easier”. And even if you're busy today just add the file tomorrow. You never know when I'll be looking for one 😜
Contact directive is mandatory (and
Expires too) but I'd suggest adding
Encryption directive too (if you have an encryption key). Of course you can add the other directives too.
There's a simple file generator at securitytxt.org, you can also check my file, Have I Been Pwned?, Report-URI, and Google has one, 1Password and Facebook as well. This Czech webhosting company and this Swiss bank have
security.txt too. Alza has added one as well.
May 25, 2021 Draft 12 has changed the date format used in
Expires from RFC 5322 to a bit simpler RFC 3339
December 27, 2020 The
Expires field is required since draft 10
May 18, 2020 Added
December 31, 2019 Emails in
Contact must have the
mailto: scheme, phone numbers the
August 13, 2019 Added
August 13, 2019 Added
Canonical directive and inline signatures, removed
Signature, added a note about links that all must be HTTPS
August 13, 2019 Added a paragraph about redirection targets on the same domain only, removed the leading dot from the filename on internal hosts and file systems
I build web applications and I'm into web application security. I like to speak about secure development. My mission is to teach web developers how to build secure and fast web applications and why.