The CVR to securitytxt Pipeline: How Ethical Hackers Are Secretly Probing Your Danish Company’s Defenses

Listen to this Post

Featured Image

Introduction:

A recent talk at BSides Copenhagen 2025 revealed how security researchers are systematically assessing Danish companies’ security readiness through public data and standardized vulnerability reporting protocols. Emil Hørning’s “CVR to security.txt” methodology demonstrates how ethical hackers leverage commercial registry data to identify organizations lacking proper security reporting channels, highlighting critical gaps in Denmark’s cybersecurity posture.

Learning Objectives:

  • Understand how security researchers map CVR data to organizational assets
  • Implement and validate security.txt protocols for vulnerability disclosure
  • Master reconnaissance techniques used in bug bounty programs
  • Deploy effective security response workflows for ethical hacker reports
  • Harden external-facing assets against unauthorized reconnaissance

You Should Know:

1. CVR Data Enumeration and Asset Discovery

The Central Business Register (CVR) contains extensive information about Danish companies that security researchers leverage for initial reconnaissance. This public data becomes the foundation for mapping organizational digital assets and identifying potential targets for security assessment.

 Python script to query CVR data and extract company domains
import requests
import json

def get_cvr_data(cvr_number):
api_url = f"https://cvrapi.dk/api?search={cvr_number}&country=dk"
headers = {'User-Agent': 'Security-Research-Tool/1.0'}

try:
response = requests.get(api_url, headers=headers)
data = response.json()

Extract potential domains from company name
company_name = data.get('name', '')
clean_name = company_name.lower().replace(' ', '').replace('-', '')
domains = [
f"https://www.{clean_name}.dk",
f"https://{clean_name}.dk", 
f"https://www.{clean_name}-group.dk"
]

return {
'name': company_name,
'address': data.get('address', ''),
'domains': domains,
'industry': data.get('industry', '')
}
except Exception as e:
print(f"Error fetching CVR data: {e}")
return None

Usage example
company_data = get_cvr_data('12345678')
print(f"Discovered domains: {company_data['domains']}")

Step-by-step guide explaining what this does and how to use it:
This script demonstrates how ethical hackers begin their reconnaissance by querying Denmark’s CVR registry to obtain basic company information. The function takes a CVR number as input, queries the official API, and generates potential domain names based on the company’s registered name. Security teams should monitor for such reconnaissance attempts in their logs and consider implementing domain name variations that don’t directly correlate with their CVR-registered names.

2. Automated security.txt Validation and Location Discovery

The security.txt file provides a standardized method for security researchers to report vulnerabilities. Ethical hackers systematically check for this file across discovered domains to determine if the organization has established proper reporting channels.

!/bin/bash
 Automated security.txt discovery script
DOMAIN="$1"

echo "[] Checking for security.txt on: $DOMAIN"

Common security.txt locations
LOCATIONS=(
"/.well-known/security.txt"
"/security.txt"
"/.well-known/security.txt.sig"
"/security.txt.sig"
)

for location in "${LOCATIONS[@]}"; do
URL="https://$DOMAIN$location"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$URL")

if [ "$HTTP_STATUS" -eq 200 ]; then
echo "[+] FOUND: $URL"
curl -s "$URL" | head -20
else
echo "[-] Not found: $URL (HTTP $HTTP_STATUS)"
fi
done

Check for security.txt in HTTP headers
echo "[] Checking HTTP headers for security policy links"
curl -s -I "https://$DOMAIN" | grep -i "security-policy|security.txt"

Step-by-step guide explaining what this does and how to use it:
This bash script automates the discovery of security.txt files across multiple standard locations. It checks both common paths and examines HTTP headers for security policy references. Organizations should deploy valid security.txt files at standardized locations and monitor for these discovery attempts as they indicate ethical hackers are attempting to follow proper disclosure channels.

3. Subdomain Enumeration and Attack Surface Mapping

Once primary domains are identified through CVR data, security researchers perform comprehensive subdomain enumeration to map the entire organizational attack surface.

 Subdomain enumeration using multiple techniques
DOMAIN="$1"

echo "[] Starting subdomain enumeration for: $DOMAIN"

Using sublist3r for initial enumeration
sublist3r -d "$DOMAIN" -o "${DOMAIN}_sublist3r.txt"

Using amass for more comprehensive discovery
amass enum -d "$DOMAIN" -o "${DOMAIN}_amass.txt"

Certificate transparency log checking
curl -s "https://crt.sh/?q=%25.${DOMAIN}&output=json" | jq -r '.[].name_value' | sort -u > "${DOMAIN}_crtsh.txt"

Combine and deduplicate results
cat "${DOMAIN}_sublist3r.txt" "${DOMAIN}_amass.txt" "${DOMAIN}_crtsh.txt" | sort -u > "${DOMAIN}_all_subdomains.txt"

Verify which subdomains are active
echo "[] Verifying active subdomains"
cat "${DOMAIN}_all_subdomains.txt" | httpx -silent -status-code > "${DOMAIN}_live_subdomains.txt"

echo "[+] Found $(wc -l < "${DOMAIN}_live_subdomains.txt") live subdomains"

Step-by-step guide explaining what this does and how to use it:
This comprehensive subdomain enumeration script uses multiple techniques including passive DNS data, certificate transparency logs, and brute-force discovery to map an organization’s entire external attack surface. Security teams should regularly run similar scripts against their own domains to maintain awareness of their external footprint and identify unauthorized or forgotten subdomains.

4. security.txt File Implementation and Validation

A properly configured security.txt file must include specific fields and follow RFC 9116 standards to be effective for vulnerability reporting.

 Example security.txt file following RFC 9116
 Place at https://example.com/.well-known/security.txt
Contact: mailto:[email protected]
Contact: https://example.com/security-contact
Encryption: https://example.com/pgp-key.txt
Acknowledgments: https://example.com/hall-of-fame
Policy: https://example.com/security-policy.html
Preferred-Languages: en, da
Expires: 2025-12-31T23:59:59.000Z
Canonical: https://example.com/.well-known/security.txt

Additional security contacts for different types of reports
Contact: mailto:[email protected]; policy=abuse
Contact: mailto:[email protected]; policy=phishing
 Validation script for security.txt files
!/bin/bash
URL="$1"

echo "[] Validating security.txt at: $URL"

Fetch the security.txt file
CONTENT=$(curl -s "$URL")

Check required fields
REQUIRED_FIELDS=("Contact" "Expires")
for field in "${REQUIRED_FIELDS[@]}"; do
if grep -q "^${field}:" <<< "$CONTENT"; then
echo "[+] Required field present: $field"
else
echo "[-] MISSING required field: $field"
fi
done

Validate expiration date
EXPIRES_DATE=$(grep -i "^Expires:" <<< "$CONTENT" | head -1)
if [ -n "$EXPIRES_DATE" ]; then
echo "[+] Security.txt expires: $EXPIRES_DATE"
else
echo "[-] No expiration date set - security.txt should expire"
fi

Check for cryptographic signature
if curl -s -f "${URL}.sig"; then
echo "[+] Found cryptographic signature"
else
echo "[-] No cryptographic signature found"
fi

Step-by-step guide explaining what this does and how to use it:
This section provides both a template for proper security.txt implementation and a validation script to ensure compliance with standards. Organizations should deploy security.txt files with multiple contact methods, clear policies, and cryptographic signatures to establish trusted communication channels with security researchers.

5. Bug Bounty Program Configuration and Management

For organizations ready to implement formal bug bounty programs, proper configuration is essential for managing researcher submissions and scaling security testing.

 bug_bounty_policy.yaml
program_name: "Example Corp Bug Bounty"
scope:
in_scope:
domains:
- ".example.com"
- "example.com"
applications:
- "Example Web Application"
- "Example Mobile App"
out_of_scope:
domains:
- "thirdparty.example.com"
systems:
- "Internal corporate network"

reward_structure:
critical: "$5000-$10000"
high: "$1000-$5000" 
medium: "$250-$1000"
low: "$100-$250"

submission_requirements:
required:
- "Proof of concept"
- "Impact analysis"
- "Suggested fix"
preferred_format: "Markdown"

safe_harbor:
terms: "We will not pursue legal action for security research conducted in accordance with this policy"
conditions:
- "Make good faith effort to avoid privacy violations"
- "Do not degrade our services" 
- "Provide reasonable time for remediation"
 Bug bounty submission triage script
import json
import re
from datetime import datetime

class BugBountyTriage:
def <strong>init</strong>(self, submission_file):
with open(submission_file, 'r') as f:
self.submission = json.load(f)

def validate_submission(self):
required_fields = ['title', 'description', 'impact', 'steps_to_reproduce']
missing_fields = []

for field in required_fields:
if field not in self.submission:
missing_fields.append(field)

if missing_fields:
return False, f"Missing required fields: {', '.join(missing_fields)}"

Validate impact assessment
impact = self.submission.get('impact', '').lower()
if not any(term in impact for term in ['data breach', 'service disruption', 'privilege escalation']):
return False, "Insufficient impact description"

return True, "Submission valid"

def assign_severity(self):
 Automated initial severity assessment
impact_keywords = {
'critical': ['remote code execution', 'auth bypass', 'sql injection'],
'high': ['xss', 'csrf', 'information disclosure'],
'medium': ['broken authentication', 'insecure direct object references'],
'low': ['clickjacking', 'security headers missing']
}

description = self.submission.get('description', '').lower()
for severity, keywords in impact_keywords.items():
if any(keyword in description for keyword in keywords):
return severity

return 'info'

Step-by-step guide explaining what this does and how to use it:
This configuration provides a framework for establishing structured bug bounty programs, including scope definition, reward structures, and submission requirements. The triage script helps automate initial validation of researcher submissions, ensuring consistent processing and rapid response to legitimate security reports.

6. Security Response Workflow Automation

Establishing automated workflows for handling security reports ensures consistent and timely responses to ethical hackers.

 Security response automation script
import smtplib
from email.mime.text import MimeText
import requests
import time

class SecurityResponse:
def <strong>init</strong>(self, config):
self.config = config

def send_initial_response(self, reporter_email, report_id):
"""Send automated initial response to security reporter"""
subject = f"Security Report Received - ID: {report_id}"
body = f"""
Thank you for your security report.

We have received your submission and our security team is reviewing it.
Report ID: {report_id}
Initial assessment expected within: 48 hours

Please include this ID in all future correspondence.

Best regards,
Security Team
"""

self._send_email(reporter_email, subject, body)

def update_bug_tracker(self, report_data):
"""Create ticket in internal bug tracking system"""
ticket_data = {
'title': report_data['title'],
'description': report_data['description'],
'severity': report_data.get('severity', 'unassigned'),
'reporter': report_data.get('reporter', 'anonymous'),
'created_date': datetime.now().isoformat()
}

response = requests.post(
self.config['bug_tracker_url'],
json=ticket_data,
auth=(self.config['api_user'], self.config['api_key'])
)

return response.json()['ticket_id']

def _send_email(self, to_email, subject, body):
msg = MimeText(body)
msg['Subject'] = subject
msg['From'] = self.config['smtp_from']
msg['To'] = to_email

with smtplib.SMTP(self.config['smtp_server']) as server:
server.send_message(msg)

Step-by-step guide explaining what this does and how to use it:
This automation script demonstrates how organizations can streamline their security response workflows by automatically acknowledging reports, creating tracking tickets, and ensuring consistent communication with researchers. Implementing such automation reduces response times and improves the experience for ethical hackers reporting vulnerabilities.

7. Continuous Security Monitoring and Reconnaissance Detection

Organizations should implement monitoring to detect reconnaissance activities and assess their external security posture continuously.

!/bin/bash
 Continuous security monitoring script
DOMAIN="$1"
BASELINE_FILE="${DOMAIN}_baseline.txt"

echo "[] Starting continuous security monitoring for: $DOMAIN"

Create baseline if it doesn't exist
if [ ! -f "$BASELINE_FILE" ]; then
echo "[] Creating baseline for $DOMAIN"
./subdomain_enumeration.sh "$DOMAIN" > "$BASELINE_FILE"
fi

Run current enumeration
./subdomain_enumeration.sh "$DOMAIN" > "${DOMAIN}_current.txt"

Compare with baseline
echo "[] Comparing with baseline"
diff "$BASELINE_FILE" "${DOMAIN}_current.txt" > "${DOMAIN}_changes.txt"

if [ -s "${DOMAIN}_changes.txt" ]; then
echo "[!] CHANGES DETECTED in attack surface"
cat "${DOMAIN}_changes.txt"

Alert security team
echo "Attack surface changes detected for $DOMAIN" | \
mail -s "Security Alert: Attack Surface Change" [email protected]
else
echo "[+] No changes in attack surface"
fi

Monitor for security.txt access attempts
echo "[] Checking security.txt access logs"
tail -100 /var/log/nginx/access.log | grep "security.txt" | \
while read line; do
ip=$(echo $line | awk '{print $1}')
echo "[!] security.txt accessed from: $ip"
 Perform threat intelligence lookup
whois "$ip" | grep -i "country|org-name" | head -2
done

Step-by-step guide explaining what this does and how to use it:
This monitoring script helps organizations detect changes in their external attack surface and identify reconnaissance activities targeting their security.txt files. Regular execution allows security teams to maintain awareness of their digital footprint and quickly identify potential security research or malicious scanning activities.

What Undercode Say:

  • The CVR-to-security.txt pipeline represents a systematic approach to measuring organizational security maturity that ethical hackers are increasingly adopting
  • Danish companies significantly underestimate their exposure to unsolicited security testing and vulnerability discovery
  • Organizations without proper security.txt implementation are effectively invisible to ethical hackers attempting responsible disclosure
  • The absence of bug bounty programs forces security researchers to choose between silent discovery and potentially illegal testing
  • Automated reconnaissance has made comprehensive asset discovery trivial, rendering “security through obscurity” completely ineffective

The methodological approach demonstrated at BSides Copenhagen 2025 highlights a critical inflection point in Denmark’s cybersecurity landscape. Ethical hackers are no longer waiting for invitations but are proactively assessing organizational readiness using publicly available data. This shift represents both a threat and opportunity: companies with proper disclosure channels benefit from free security testing, while those without risk exposure through uncoordinated testing or silent discovery of vulnerabilities. The Danish business community must recognize that standardized security protocols like security.txt have transitioned from best practice to essential infrastructure.

Prediction:

Within two years, the absence of security.txt files and clear vulnerability disclosure policies will become a measurable business risk factor for Danish companies, potentially affecting cyber insurance premiums and compliance requirements. As tools like those demonstrated at BSides Copenhagen become more accessible, we’ll see a 300% increase in unsolicited security testing against Danish organizations. Companies embracing this trend through bug bounty programs will identify and remediate critical vulnerabilities 5x faster than those relying solely on traditional security assessments, creating a significant competitive advantage in security posture and resilience.

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Abdallahajjawi I – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky