{"id":54634,"date":"2026-09-01T11:33:06","date_gmt":"2026-09-01T09:33:06","guid":{"rendered":"https:\/\/cyberant.com\/what-is-security-txt-and-how-do-you-set-it-up-correctly\/"},"modified":"2026-09-01T11:33:06","modified_gmt":"2026-09-01T09:33:06","slug":"what-is-security-txt-and-how-do-you-set-it-up-correctly","status":"publish","type":"post","link":"https:\/\/cyberant.com\/en\/what-is-security-txt-and-how-do-you-set-it-up-correctly\/","title":{"rendered":"What is security.txt, and how do you set it up correctly?"},"content":{"rendered":"<p>Suppose a security researcher finds a vulnerability in your web application. Does that person know where to report it? For many Dutch organizations, the answer is no. The next question is whether and how the report will reach the security team. A security.txt file solves that problem. Below, you\u2019ll learn what it should contain, where it should be placed, and what often goes wrong in practice.     <\/p>\n<h2>What is security.txt?<\/h2>\n<p>Security.txt is a text file on your web server that specifies how someone can report a security issue to your organization. The format is defined in <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9116.html\" target=\"_blank\" rel=\"noopener\">RFC 9116<\/a>, published in April 2022 by Edwin Foudil and Yakov Shafranovich. <\/p>\n<p>The structure is similar to robots.txt: a fixed location on your domain, a fixed format, and a file that can be read by both humans and scripts. Each line consists of a field name, a colon, and a value. Lines that begin with a hash sign are comments.  <\/p>\n<h2>Why should you include a security.txt file?<\/h2>\n<p>Otherwise, the person reporting the issue will have to look elsewhere. Someone who discovers a vulnerability in your customer portal has four options: they can keep searching until they find the right person, send an email to the general email address, give up, or post their findings on social media. Only with the first option will you be the first to know.  <\/p>\n<p>Ethical hackers, security researchers, and technically savvy customers regularly report vulnerabilities to companies that aren\u2019t equipped to handle them at all. Here\u2019s what happens: the report comes in to info@, sits there for two weeks, and the reporter concludes that you apparently aren\u2019t interested. Out of frustration or concern about the vulnerability, the reporter may then decide to go public\u2014something you\u2019ll likely want to avoid.  <\/p>\n<p>There\u2019s also an internal benefit. By creating a security.txt file, you force yourself to determine in advance who will handle reports, within what timeframe a response will be provided, and who will decide on an emergency patch. You\u2019ll want to have that discussion before the first report comes in.  <\/p>\n<h2>Where should the file be located?<\/h2>\n<p>On  <code>https:\/\/jouwdomein.nl\/.well-known\/security.txt<\/code>. That is the only correct location according to RFC 9116. There are three requirements associated with it: <\/p>\n<ul>\n<li>The file must be accessible via HTTPS.<\/li>\n<li>It must be served as <code>text\/plain<\/code>, with UTF-8 character encoding.<\/li>\n<li>If there is also a file in the webroot (<code>\/security.txt<\/code>), then according to the RFC, the version at <code>\/.well-known\/<\/code> takes precedence. You can use that old location as a redirect, so that anyone who still tries to access it will end up in the right place. <\/li>\n<\/ul>\n<p>If you work with multiple domains or standalone subdomains, each domain where someone might find a vulnerability needs its own file. Use the &#8220;Canonical&#8221; field to point to where the original should be located. <\/p>\n<h2>What fields are included in a security.txt file?<\/h2>\n<p>Two fields are required:<\/p>\n<ul>\n<li><strong>Contact<\/strong> &#8211; where you send the report. An email address (<code>mailto:<\/code>), a phone number (<code>tel:<\/code>), or a web form (<code>https:<\/code>). This field may appear multiple times; the order indicates your preference.  <\/li>\n<li><strong>Expires<\/strong> &#8211; the date on which the information in this file is considered outdated. This field may appear exactly once. <\/li>\n<\/ul>\n<p>The rest is optional:<\/p>\n<ul>\n<li><strong>Encryption<\/strong> &#8211; a link to your public key, so that a reporter can send the details in encrypted form.<\/li>\n<li><strong>Policy<\/strong> &#8211; a link to your CVD policy or responsible disclosure page.<\/li>\n<li><strong>Acknowledgments<\/strong> \u2014a page where you thank your contributors.<\/li>\n<li><strong>Preferred Languages<\/strong> &#8211; the languages in which you would like to receive notifications. You may select only one option. <\/li>\n<li><strong>Canonical<\/strong> \u2014the place where this file belongs.<\/li>\n<li><strong>Hiring<\/strong> &#8211; a link to your security job openings.<\/li>\n<\/ul>\n<h2>What does a good security.txt file look like?<\/h2>\n<pre><code># Meldingen over de beveiliging van onze systemen zijn welkom.\nContact: mailto:security@jouwdomein.nl\nContact: tel:+31-88-1234567\nExpires: 2027-09-01T00:00:00.000Z\nEncryption: https:\/\/jouwdomein.nl\/pgp-key.txt\nPolicy: https:\/\/jouwdomein.nl\/responsible-disclosure\nAcknowledgments: https:\/\/jouwdomein.nl\/hall-of-fame\nPreferred-Languages: nl, en\nCanonical: https:\/\/jouwdomein.nl\/.well-known\/security.txt\n<\/code><\/pre>\n<p>Note the address listed under \u201cContact.\u201d A shared mailbox like security@ will continue to function even if a colleague leaves, whereas a personal email address will quietly become inactive after a year. <\/p>\n<h2>Why does security.txt have an expiration date?<\/h2>\n<p>Because outdated contact information is worse than no contact information at all. Anyone who sends an email to an address that no one checks anymore will assume the message was delivered. The &#8220;Expires&#8221; field shows when the file was last checked, and the RFC recommends setting the date to less than one year in the future.  <\/p>\n<p>Therefore, make sure to add the expiration date to the calendar of the person in charge of management, or have your hosting provider include the file in their annual maintenance. An expired security.txt file is a sign to researchers that the rest of the site is likely out of date as well. <\/p>\n<h2>Do you need to sign your security.txt file with PGP?<\/h2>\n<p>The RFC recommends an OpenPGP signature, in combination with the Canonical field, so that a reporter can verify that the file truly comes from you and is in the correct location. This allows the reporter to verify that the file has not been tampered with. Keep in mind, nothing is more confusing than an incorrect signature. Therefore, start with a correctly filled-out file that includes a current address and a valid \u201cExpires\u201d date.   <\/p>\n<h2>What is the difference between security.txt and a responsible disclosure page?<\/h2>\n<p>They go hand in hand and serve different purposes. A responsible disclosure page, also known as a Coordinated Vulnerability Disclosure (CVD), is a page on your website that outlines the ground rules: what you expect from a reporter and what they can expect from you. This page is written for people, is hosted at a URL of your choice, and can be as long as necessary.  <\/p>\n<p>Security.txt serves as the guide to that page. The file is located in a specified directory, is machine-readable, and contains little more than a contact address and a link to that page. A scanner, an investigation tool, or an AI assistant that determines where a report should be sent first checks <code>\/.well-known\/security.txt<\/code>.  <\/p>\n<p>That\u2019s the main weakness of a standalone disclosure page: it can only be found if someone stumbles upon it in your footer or knows how to Google it. If it\u2019s located in a logical spot, things usually go well, and the security.txt file is the icing on the cake. Do you already have a responsible disclosure page? Then you\u2019ll be done in five minutes. Enter the URL of that page in the \u201cPolicy\u201d field, the email address in the \u201cContact\u201d field, and place the file in the correct location.    <\/p>\n<h2>What do you include in the CVD policy you&#8217;re referring to?<\/h2>\n<p>The &#8220;Policy&#8221; field refers to your Coordinated Vulnerability Disclosure or Responsible Disclosure policy. It outlines what you expect from a reporter and what the reporter can expect from you. It should definitely include the following four components:  <\/p>\n<ul>\n<li>The scope: which domains, applications, and systems are covered, and what types of attacks you specifically do not want (denial-of-service attacks, social engineering targeting your employees, downloading customer data).<\/li>\n<li>What you commit to: the number of business days within which you will send a confirmation of receipt, when you will provide substantive feedback, and the target resolution timeframe.<\/li>\n<li>Whether you provide credit or a reward, and where that credit will appear.<\/li>\n<li>A commitment not to take legal action against reporters who follow your rules. In the Netherlands, <\/li>\n<\/ul>\n<p>The NCSC has published <a href=\"https:\/\/www.ncsc.nl\/onderwerpen\/cvd-beleid\" target=\"_blank\" rel=\"noopener\">guidelines<\/a> on this topic that you can use as a starting point.<\/p>\n<h2>Is security.txt required?<\/h2>\n<p>No. RFC 9116 has the status &#8220;Informational,&#8221; which means it is a widely accepted convention and not a standard that you are required to comply with. <\/p>\n<p>The Cybersecurity Act\u2014the Dutch implementation of NIS2, which has been in effect since August 15, 2026, for more than 8,000 organizations\u2014does not mention security.txt anywhere. What the law does require is that you manage risks and report incidents to the CSIRT within 24 hours. A reporting channel that demonstrably works is part of that first requirement, and security.txt is the most cost-effective way to make that channel discoverable. The question is also coming up more and more frequently in ISO 27001 audits and supplier questionnaires.   <\/p>\n<h2>What goes wrong in practice?<\/h2>\n<p>We keep finding the same errors on the websites we examine. A file with an &#8220;Expires&#8221; date that expired two years ago. A contact address for an administrator who now works elsewhere. A security.txt file located only in the webroot and not in <code>\/.well-known\/<\/code>. A Policy link pointing to a page that disappeared during the last website migration.    <\/p>\n<p>There\u2019s an even more subtle one: a server that returns a clean HTML page with a 200 status code for every unknown URL. A scanner then reads a security.txt file that doesn\u2019t exist, and you think the issue is resolved. That\u2019s why you should always check the status code and the content type\u2014not just what your browser displays.  <\/p>\n<h2>Does a security.txt file increase your risk of being hacked?<\/h2>\n<p>The file does not contain any information that would be useful to an attacker. You are publishing a contact address, not version numbers or internal system names. <\/p>\n<p>What you do get is noise. There\u2019s a category of senders who circulate automated scan reports asking for a reward, even though there\u2019s no actual vulnerability behind them. Therefore, agree in advance on who will review these messages and how you\u2019ll distinguish between a legitimate report and a form letter. That\u2019s a small price to pay to ensure that a researcher who does find a real vulnerability can reach you immediately.   <\/p>\n<h2>How do you check if your security.txt file is correct?<\/h2>\n<p>Start with the basics and retrieve the file the way a scanner would:<\/p>\n<pre><code>curl -i https:\/\/jouwdomein.nl\/.well-known\/security.txt\n<\/code><\/pre>\n<p>You want to see a 200 status code, a \u201c <code>Content-Type<\/code> \u201d from <code>text\/plain<\/code>, and an \u201cExpires\u201d date that\u2019s in the future. After that, the most important test is the human one: send a test message to the address listed under \u201cContact\u201d and see if someone responds within your own promised timeframe. A file that\u2019s technically correct but ends up in a mailbox that no one opens is still a dead end.  <\/p>\n<h2>A doorbell is not a lock<\/h2>\n<p>Security.txt ensures that you\u2019re notified when someone finds something. It says nothing about what can be found. These two things go hand in hand: an organization that takes reports seriously but never conducts its own testing is, in effect, waiting for an outsider to do the work.  <\/p>\n<p>Want to know what vulnerabilities are already present in your environment? During a <a href=\"https:\/\/cyberant.com\/en\/pen_test\/\">penetration test<\/a>, our certified ethical hackers go beyond an automated scan: we manually search for what a scanner misses, and then explain to you in plain language where the vulnerabilities are. <a href=\"https:\/\/cyberant.com\/en\/contact\/\">Schedule a consultation<\/a>, and we\u2019ll work with you to assess your current situation. <\/p>\n<p><script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Wat is security.txt?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Security.txt is een tekstbestand op je webserver waarin staat hoe iemand een beveiligingsprobleem bij jouw organisatie kan melden. Het formaat is vastgelegd in RFC 9116, gepubliceerd in april 2022. Elke regel bestaat uit een veldnaam, een dubbele punt en een waarde.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Waar moet het security.txt-bestand staan?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Op https:\/\/jouwdomein.nl\/.well-known\/security.txt. Het bestand moet via https bereikbaar zijn en worden uitgeserveerd als text\/plain met tekencodering utf-8. Staat er ook een bestand in de webroot, dan geldt volgens RFC 9116 de versie in \/.well-known\/.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Welke velden zijn verplicht in security.txt?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Contact en Expires zijn verplicht. Contact geeft aan waar een melding naartoe moet en mag meerdere keren voorkomen, waarbij de volgorde de voorkeur aangeeft. Expires geeft aan wanneer de informatie als verouderd geldt en mag precies een keer voorkomen. Optioneel zijn Encryption, Policy, Acknowledgments, Preferred-Languages, Canonical en Hiring.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Wat is het verschil tussen security.txt en een responsible disclosure-pagina?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Een responsible disclosure-pagina, ook wel CVD-pagina, is een webpagina voor mensen met je spelregels erop: wat je van een melder verwacht en wat hij van jou mag verwachten. Security.txt is de machine-leesbare wegwijzer ernaartoe, op de vaste locatie \/.well-known\/security.txt, met een contactadres en een link naar die pagina achter het veld Policy. Zonder security.txt is de disclosure-pagina alleen te vinden via je footer of via een zoekmachine.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Waarom heeft security.txt een vervaldatum?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Het veld Expires maakt zichtbaar of het bestand nog is nagelopen, zodat een melder niet mailt naar een adres dat niemand meer leest. RFC 9116 beveelt aan de datum minder dan een jaar in de toekomst te zetten.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Is security.txt verplicht?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Nee. RFC 9116 heeft de status Informational en is een breed geaccepteerde afspraak, geen norm. De Cyberbeveiligingswet, de Nederlandse invulling van NIS2 die sinds 15 augustus 2026 van kracht is, noemt security.txt niet. Die wet vraagt wel om risicobeheersing en om incidentmelding binnen 24 uur bij het CSIRT, en een vindbaar meldkanaal hoort daarbij.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Moet je security.txt ondertekenen met PGP?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"RFC 9116 beveelt een OpenPGP-handtekening aan in combinatie met het veld Canonical, zodat een melder kan controleren dat het bestand van jou komt. Voor de meeste MKB-organisaties weegt zwaarder dat het bestand een actueel contactadres en een geldige Expires-datum heeft; ondertekenen kan daarna.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Hoe controleer je of je security.txt klopt?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Haal het bestand op met curl -i https:\/\/jouwdomein.nl\/.well-known\/security.txt en controleer of je statuscode 200 krijgt, een Content-Type van text\/plain en een Expires-datum in de toekomst. Stuur daarna een testmelding naar het adres achter Contact om te controleren of iemand die mailbox daadwerkelijk leest.\"\n      }\n    }\n  ]\n}\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Security.txt tells researchers where they can report a vulnerability in your systems. An explanation of RFC 9116, all fields, a working example, and the errors we most commonly encounter in practice. <\/p>\n","protected":false},"author":5,"featured_media":54631,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[206,216],"tags":[346,215,345,344,347],"class_list":["post-54634","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cyber-security","category-knowledge-base","tag-cvd","tag-responsible-disclosure-en","tag-rfc-9116","tag-security-txt","tag-vulnerability-disclosure"],"_links":{"self":[{"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/posts\/54634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/comments?post=54634"}],"version-history":[{"count":0,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/posts\/54634\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/media\/54631"}],"wp:attachment":[{"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/media?parent=54634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/categories?post=54634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cyberant.com\/en\/wp-json\/wp\/v2\/tags?post=54634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}