Menu

ISM-1717 Implementation Guide: Security.txt File Requirements

January 27, 2025
by Kieran Jessup

ISM-1717 Implementation Guide: Security.txt File Requirements

Overview

ISM-1717 mandates that organizations host a security.txt file for each internet-facing website domain. This control is based on RFC 9116, which defines the standard format and location for security contact information.

Control Requirements

ISM-1717: Organizations must host a security.txt file at the /.well-known/security.txt path for each internet-facing website domain.

Implementation Steps

1. File Location and Access

The security.txt file must be accessible at:

https://yourdomain.com/.well-known/security.txt

2. File Format Requirements

The file must be served as plain text with the MIME type text/plain and UTF-8 encoding.

3. Required Fields

Contact Information

Contact: mailto:security@yourdomain.com
Contact: https://yourdomain.com/security
Encryption: https://yourdomain.com/pgp-key.txt

Acknowledgments

Acknowledgments: https://yourdomain.com/hall-of-fame

Policy

Policy: https://yourdomain.com/security-policy

Hiring

Hiring: https://yourdomain.com/careers

4. Complete Example

# Security Contact Information for yourdomain.com
# This file follows RFC 9116

Contact: mailto:security@yourdomain.com
Contact: https://yourdomain.com/security
Encryption: https://yourdomain.com/pgp-key.txt
Acknowledgments: https://yourdomain.com/hall-of-fame
Policy: https://yourdomain.com/security-policy
Hiring: https://yourdomain.com/careers
Expires: 2025-12-31T23:59:59.000Z
Preferred-Languages: en, fr
Canonical: https://yourdomain.com/.well-known/security.txt

Technical Implementation

Web Server Configuration

Apache Configuration

# Add to .htaccess or server config
<Location "/.well-known/security.txt">
    Header set Content-Type "text/plain; charset=utf-8"
    Header set Cache-Control "no-cache"
</Location>

Nginx Configuration

location /.well-known/security.txt {
    add_header Content-Type "text/plain; charset=utf-8";
    add_header Cache-Control "no-cache";
}

IIS Configuration

<location path=".well-known/security.txt">
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Content-Type" value="text/plain; charset=utf-8" />
                <add name="Cache-Control" value="no-cache" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</location>

Content Management System Integration

WordPress

  1. Create the file at wp-content/.well-known/security.txt
  2. Add rewrite rules to wp-content/.htaccess:
RewriteEngine On
RewriteRule ^\.well-known/security\.txt$ wp-content/.well-known/security.txt [L]

Drupal

  1. Place file in sites/default/files/.well-known/security.txt
  2. Configure web server to serve from /.well-known/security.txt

Validation and Testing

Automated Testing

# Test file accessibility
curl -I https://yourdomain.com/.well-known/security.txt

# Validate content type
curl -H "Accept: text/plain" https://yourdomain.com/.well-known/security.txt

Manual Verification Checklist

  • File accessible at /.well-known/security.txt
  • Returns HTTP 200 status code
  • Content-Type is text/plain; charset=utf-8
  • All required fields are present
  • Contact email is valid and monitored
  • URLs in the file are accessible
  • Expires field is set to a future date

Security Considerations

Information Disclosure

  • Only include publicly available contact information
  • Avoid exposing internal network details
  • Consider using a dedicated security contact email

Email Security

  • Use a monitored security@ email address
  • Implement proper email filtering
  • Consider using PGP encryption for sensitive reports

URL Security

  • Ensure all referenced URLs use HTTPS
  • Validate that linked pages are accessible
  • Regularly update expired links

Compliance Monitoring

Automated Checks

import requests
import re
from datetime import datetime

def validate_security_txt(domain):
    url = f"https://{domain}/.well-known/security.txt"
    
    try:
        response = requests.get(url, timeout=10)
        
        if response.status_code != 200:
            return False, f"HTTP {response.status_code}"
            
        if "text/plain" not in response.headers.get("content-type", ""):
            return False, "Invalid content type"
            
        content = response.text
        
        # Check for required fields
        if "Contact:" not in content:
            return False, "Missing Contact field"
            
        # Check expiration
        expires_match = re.search(r"Expires:\s*(.+)", content)
        if expires_match:
            expires_date = datetime.fromisoformat(expires_match.group(1).replace('Z', '+00:00'))
            if expires_date < datetime.now(expires_date.tzinfo):
                return False, "File has expired"
                
        return True, "Valid security.txt file"
        
    except Exception as e:
        return False, f"Error: {str(e)}"

Regular Audits

  • Monthly validation of file accessibility
  • Quarterly review of contact information
  • Annual update of expiration dates
  • Continuous monitoring of linked resources

Common Issues and Solutions

Issue: File Not Found (404)

Solution: Verify file path and web server configuration

Issue: Wrong Content Type

Solution: Configure web server to serve as text/plain

Issue: Expired File

Solution: Update the Expires field with a future date

Issue: Invalid Email Format

Solution: Ensure email addresses follow RFC 5322 format

Integration with Security Programs

Bug Bounty Programs

  • Include bug bounty policy URL
  • Specify scope and rewards
  • Link to responsible disclosure policy

Vulnerability Disclosure

  • Establish clear reporting process
  • Define response timeframes
  • Provide encryption options

Security Team Contact

  • Dedicated security email
  • Alternative contact methods
  • Escalation procedures

Maintenance and Updates

Regular Tasks

  • Monthly: Verify file accessibility
  • Quarterly: Update contact information
  • Annually: Review and refresh content
  • As needed: Update policy URLs

Change Management

  • Document all changes to security.txt
  • Test changes in staging environment
  • Update related documentation
  • Notify security team of changes

Conclusion

Implementing ISM-1717 security.txt requirements provides a standardized way for security researchers to contact your organization. Following RFC 9116 ensures compatibility and best practices while meeting compliance requirements.

Regular monitoring and maintenance of the security.txt file ensures continued compliance and effective security communication channels.

References