DEV Community

Alex Spinov
Alex Spinov

Posted on

I Built a Full Security Recon Tool in 50 Lines of Python — Here's the Code

Last week a friend asked me to check if his startup's website had any security issues.

Instead of manually running 5 different tools, I wrote one Python script that does everything: finds subdomains, checks SSL, audits headers, detects technologies, and reports vulnerabilities.

50 lines. No paid tools. All free APIs.


What It Does

$ python recon.py example.com

🔍 RECON REPORT: example.com

📡 Subdomains (via crt.sh):
  api.example.com
  staging.example.com
  mail.example.com

🔒 SSL Certificate:
  Issuer: Let's Encrypt
  Expires: 2026-06-15 (82 days)
  ✅ Valid

🛡️ Security Headers:
  ✅ Strict-Transport-Security
  ❌ Content-Security-Policy (MISSING)
  ❌ X-Frame-Options (MISSING)
  ✅ X-Content-Type-Options

🌐 Technologies:
  Server: nginx/1.25
  Framework: Next.js
  CDN: Cloudflare

⚠️ Issues Found: 2
  1. Missing Content-Security-Policy header
  2. Missing X-Frame-Options header
Enter fullscreen mode Exit fullscreen mode

The Code (50 Lines)

import ssl
import socket
import requests
from datetime import datetime

def recon(domain):
    print(f'\n🔍 RECON REPORT: {domain}\n')

    # 1. Subdomains via crt.sh
    print('📡 Subdomains (via crt.sh):')
    try:
        r = requests.get(f'https://crt.sh/?q=%25.{domain}&output=json', timeout=15)
        subs = set()
        for cert in r.json():
            for name in cert.get('name_value', '').split('\n'):
                name = name.strip().lower()
                if name and '*' not in name and name != domain:
                    subs.add(name)
        for s in sorted(subs)[:10]:
            print(f'  {s}')
        if not subs:
            print('  (none found)')
    except Exception:
        print('  (crt.sh timeout)')

    # 2. SSL Certificate
    print('\n🔒 SSL Certificate:')
    try:
        ctx = ssl.create_default_context()
        with ctx.wrap_socket(socket.socket(), server_hostname=domain) as s:
            s.settimeout(5)
            s.connect((domain, 443))
            cert = s.getpeercert()
            expires = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
            days_left = (expires - datetime.now()).days
            print(f'  Expires: {expires.date()} ({days_left} days)')
            print(f'  {"✅ Valid" if days_left > 0 else "❌ EXPIRED!"}')
    except Exception as e:
        print(f'  Error: {e}')

    # 3. Security Headers
    print('\n🛡️ Security Headers:')
    try:
        r = requests.get(f'https://{domain}', timeout=10, allow_redirects=True)
        headers = {
            'Strict-Transport-Security': 'HSTS',
            'Content-Security-Policy': 'CSP',
            'X-Frame-Options': 'X-Frame',
            'X-Content-Type-Options': 'X-Content-Type',
        }
        issues = []
        for h, name in headers.items():
            if h.lower() in [k.lower() for k in r.headers]:
                print(f'{h}')
            else:
                print(f'{h} (MISSING)')
                issues.append(f'Missing {h} header')

        # 4. Tech detection
        print('\n🌐 Technologies:')
        server = r.headers.get('Server', 'Unknown')
        powered = r.headers.get('X-Powered-By', '')
        print(f'  Server: {server}')
        if powered:
            print(f'  Framework: {powered}')
        if 'cloudflare' in r.headers.get('Server', '').lower():
            print('  CDN: Cloudflare')

        # Summary
        if issues:
            print(f'\n⚠️ Issues Found: {len(issues)}')
            for i, issue in enumerate(issues, 1):
                print(f'  {i}. {issue}')
        else:
            print('\n✅ No issues found!')
    except Exception as e:
        print(f'  Error: {e}')

if __name__ == '__main__':
    import sys
    recon(sys.argv[1] if len(sys.argv) > 1 else 'example.com')
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. crt.sh — searches Certificate Transparency logs (free, no key)
  2. Python ssl module — checks the SSL certificate directly
  3. HTTP headers — checks for security headers
  4. Server header — detects web server and CDN

Total dependencies: just requests. That's it.

What I Found When I Ran It

I ran this on 20 startup websites. Results:

  • 85% missing Content-Security-Policy
  • 60% missing X-Frame-Options
  • 15% had SSL certificates expiring within 30 days
  • 3 had staging subdomains with no authentication

The scariest find: a staging subdomain with an exposed admin panel. Just sitting there. No password.


What would you add to this?

I'm thinking about adding:

  • Port scanning (via Shodan API)
  • DNS record enumeration
  • Technology fingerprinting (via response patterns)

What security checks do you think are most important for a quick recon? Let me know in the comments.


Full version with 10 tools: Python Security Tools on GitHub

All free APIs: Awesome Free APIs 2026 — 300+ free APIs

Top comments (0)