60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""
|
||
Security utilities for Funguy Bot plugins.
|
||
"""
|
||
|
||
import ipaddress
|
||
import socket
|
||
import logging
|
||
|
||
logger = logging.getLogger("security_utils")
|
||
|
||
# Networks considered unsafe for outbound connections
|
||
PRIVATE_RANGES = [
|
||
ipaddress.ip_network('10.0.0.0/8'),
|
||
ipaddress.ip_network('172.16.0.0/12'),
|
||
ipaddress.ip_network('192.168.0.0/16'),
|
||
ipaddress.ip_network('127.0.0.0/8'),
|
||
ipaddress.ip_network('169.254.0.0/16'), # link‑local
|
||
ipaddress.ip_network('0.0.0.0/8'), # "this" network
|
||
ipaddress.ip_network('::1/128'), # IPv6 loopback
|
||
ipaddress.ip_network('fc00::/7'), # unique local
|
||
ipaddress.ip_network('fe80::/10'), # link‑local
|
||
ipaddress.ip_network('::/128'), # unspecified
|
||
]
|
||
|
||
def is_public_destination(target: str) -> bool:
|
||
"""
|
||
Returns True if `target` (hostname or IP) does NOT resolve to any
|
||
private, loopback, or link‑local address.
|
||
"""
|
||
try:
|
||
# Try parsing as an IP address first
|
||
addr = ipaddress.ip_address(target)
|
||
if any(addr in net for net in PRIVATE_RANGES):
|
||
return False
|
||
return True
|
||
except ValueError:
|
||
pass
|
||
|
||
# Resolve hostname to IPs
|
||
try:
|
||
addrinfo = socket.getaddrinfo(target, None)
|
||
for _, _, _, _, sockaddr in addrinfo:
|
||
ip = sockaddr[0]
|
||
addr = ipaddress.ip_address(ip)
|
||
if any(addr in net for net in PRIVATE_RANGES):
|
||
return False
|
||
return True
|
||
except Exception as e:
|
||
logger.warning(f"Cannot resolve {target}: {e}")
|
||
return False
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# No‑op command handler – prevents bot crash because funguy.py calls
|
||
# handle_command() on every module in the plugins directory.
|
||
# ---------------------------------------------------------------------------
|
||
async def handle_command(room, message, bot, prefix, config):
|
||
"""This module is not a command plugin; ignore all messages."""
|
||
pass
|