!headers <url>")
return
original_input = args[0].strip()
url = original_input
if not url.startswith(('http://', 'https://')):
url = 'https://' + url
parsed = urlparse(url)
host = parsed.hostname
if not is_public_destination(host):
await bot.api.send_text_message(room.room_id, "❌ Private/internal addresses are not allowed.")
return
safe_input = html_escape(original_input)
safe_host = html_escape(host)
await bot.api.send_text_message(room.room_id, f"🔍 Analyzing security headers for: {safe_input}...")
final_url, status_code, http_headers, redirects_to_https = await analyze_http_response(url)
_, https_headers = await analyze_https_response(url) if url.startswith('https://') else (None, {})
headers = https_headers or http_headers
cert_info = None
if url.startswith('https://'):
cert_info = await _run_in_thread(_get_cert_info, host)
score = calculate_score(headers, redirects_to_https, cert_info)
recommendations = generate_recommendations(headers, redirects_to_https)
sections = []
# Score
score_emoji = "🟢" if score >= 80 else "🟡" if score >= 60 else "🔴"
sections.append({
"title": f"{score_emoji} Security Score",
"rows": [("", "Score", f"{score}/100")]
})
# Basic Information
basic_rows = [
("🌐", "Final URL", final_url),
("📊", "Status Code", str(status_code) if status_code else "N/A"),
("🔐", "HTTPS Redirect", "✅ Yes" if redirects_to_https else "❌ No"),
]
sections.append({"title": "📊 Basic Information", "rows": basic_rows})
# Security Headers
security_headers = {
'Strict-Transport-Security': ('🔒', 'HSTS'),
'Content-Security-Policy': ('🛡️', 'CSP'),
'X-Frame-Options': ('🚫', 'Frame Options'),
'X-Content-Type-Options': ('📄', 'Content Type'),
'X-XSS-Protection': ('❌', 'XSS Protection'),
'Referrer-Policy': ('🔗', 'Referrer Policy'),
'Permissions-Policy': ('🔧', 'Permissions Policy'),
'Feature-Policy': ('⚙️', 'Feature Policy'),
}
header_rows = []
for hdr, (emoji, label) in security_headers.items():
if hdr in headers:
val = headers[hdr][:100]
header_rows.append((emoji, label, f"✅ {val}"))
else:
header_rows.append((emoji, label, "❌ Missing"))
sections.append({"title": "🛡️ Security Headers", "rows": header_rows})
# Other Headers
other_rows = []
for hdr in ['Server', 'X-Powered-By']:
if hdr in headers:
other_rows.append(("🔍", hdr, headers[hdr]))
if other_rows:
sections.append({"title": "📋 Other Headers", "rows": other_rows})
# SSL Certificate
if cert_info:
ssl_rows = [
("📜", "Subject", cert_info['subject'].get('commonName', 'N/A')),
("🏢", "Issuer", cert_info['issuer'].get('organizationName', 'N/A')),
("📅", "Expires", cert_info.get('not_after', 'N/A')),
]
san = [san[1] for san in cert_info.get('san', []) if san[0] == 'DNS']
if san:
ssl_rows.append(("🌐", "SANs", ", ".join(san[:5])))
sections.append({"title": "🔐 SSL Certificate", "rows": ssl_rows})
# Recommendations
if recommendations:
rec_rows = [("💡", "Recommendation", rec) for rec in recommendations]
sections.append({"title": "💡 Recommendations", "rows": rec_rows})
block = code_block(f"🔒 Security Headers: {safe_host}", sections)
output = collapsible_summary(f"🔒 Headers: {safe_host}", block)
await bot.api.send_markdown_message(room.room_id, output)
# ---------------------------------------------------------------------------
# Plugin Metadata
# ---------------------------------------------------------------------------
__version__ = "1.1.2"
__author__ = "Funguy Bot"
__description__ = "HTTP security header analysis"
__help__ = """
!headers <url> – Analyzes security headers, SSL cert, gives score and recommendations in a clean, aligned table.