Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
**Learning:** In fast-path validation blocks handling polymorphic object types (like `IPv4Address` vs `IPv6Address`), using an explicit type check followed by direct attribute access (e.g., `type(ip_obj) is ipaddress.IPv6Address and ip_obj.scope_id`) is faster than using `getattr(ip_obj, 'scope_id', None)`.
**Action:** Replace `getattr` with exact `type() is X` checks and direct property access in hot-paths where specific types are known to hold unique properties (like IPv6's `ipv4_mapped` or `scope_id`), to bypass the internal dictionary lookup and exception handling overhead of dynamic attribute access.

## 2026-05-15 - Prevent redundant IPv4Address instantiations during SSRF checks
**Learning:** Python's `ipaddress` module's properties for embedded IPv4 addresses (`ipv4_mapped`, `sixtofour`, and `teredo`) compute and instantiate new `IPv4Address` objects every time they are accessed. Doing `if ip_obj.ipv4_mapped is not None: mapped = ip_obj.ipv4_mapped` parses and instantiates the embedded IPv4 object twice, which causes unnecessary overhead.
**Action:** When working with these `ipaddress` properties, cache them to local variables first before checking `is not None` using a nested `if/else` structure to avoid redundant object instantiations and parsing.

## 2024-05-09 - Redundant attributes in Python ipaddress
**Learning:** By definition in Python's `ipaddress` module, `is_private`, `is_loopback`, `is_link_local`, `is_unspecified`, and `is_reserved` inherently evaluate as `is_global = False`. Evaluating them sequentially in an SSRF blocklist is highly redundant and slow.
**Action:** When validating IPs for global routability, replace long chains like `ip.is_private or ip.is_loopback or ...` with a significantly faster logical reduction: `not ip.is_global or ip.is_multicast or (type(ip) is ipaddress.IPv6Address and ip.is_site_local)`. This reduces 8 checks down to 3 and yields massive performance gains on public IPs.
57 changes: 32 additions & 25 deletions testping1.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,34 +115,41 @@ def is_reachable(ip, timeout=1):
# shorter chain yields a ~60-80% speedup per public IP evaluated.
is_blocked = not ip_obj.is_global or ip_obj.is_multicast or (type(ip_obj) is ipaddress.IPv6Address and ip_obj.is_site_local)
if not is_blocked and type(ip_obj) is ipaddress.IPv6Address:
if ip_obj.ipv4_mapped is not None:
mapped = ip_obj.ipv4_mapped
# ⚑ Bolt: Cache embedded IPv4 addresses locally to avoid redundant instantiations.
# Calling ip_obj.ipv4_mapped computes and returns a new IPv4Address object every time.
# Caching it once locally bypasses re-parsing overhead if the value is not None,
# providing measurable performance improvements during high-frequency SSRF validation.
mapped = ip_obj.ipv4_mapped
if mapped is not None:
is_blocked = not mapped.is_global or mapped.is_multicast
elif ip_obj.sixtofour is not None:
s2f = ip_obj.sixtofour
is_blocked = not s2f.is_global or s2f.is_multicast
elif ip_obj.teredo is not None:
t_srv, t_cli = ip_obj.teredo
is_blocked = (
not t_srv.is_global or t_srv.is_multicast or
not t_cli.is_global or t_cli.is_multicast
)
else:
# πŸ›‘οΈ Sentinel: Unpack NAT64 (RFC 6052), IPv4-compatible (RFC 4291), and ISATAP (RFC 5214) addresses manually
# as Python's ipaddress module does not natively unwrap them for SSRF checks.
ip_int = int(ip_obj)
unwrapped = None
if ip_int >> 32 == 0x0064ff9b0000000000000000: # NAT64 64:ff9b::/96
unwrapped = ipaddress.IPv4Address(ip_int & 0xFFFFFFFF)
elif ip_int < 2**32 and ip_int not in (0, 1): # IPv4-compatible ::w.x.y.z
unwrapped = ipaddress.IPv4Address(ip_int)
s2f = ip_obj.sixtofour
if s2f is not None:
is_blocked = not s2f.is_global or s2f.is_multicast
else:
isatap_id = (ip_int >> 32) & 0xFFFFFFFF
if isatap_id in (0x00005efe, 0x02005efe): # ISATAP tunnel
unwrapped = ipaddress.IPv4Address(ip_int & 0xFFFFFFFF)

if unwrapped is not None:
is_blocked = not unwrapped.is_global or unwrapped.is_multicast
teredo = ip_obj.teredo
if teredo is not None:
t_srv, t_cli = teredo
is_blocked = (
not t_srv.is_global or t_srv.is_multicast or
not t_cli.is_global or t_cli.is_multicast
)
else:
# πŸ›‘οΈ Sentinel: Unpack NAT64 (RFC 6052), IPv4-compatible (RFC 4291), and ISATAP (RFC 5214) addresses manually
# as Python's ipaddress module does not natively unwrap them for SSRF checks.
ip_int = int(ip_obj)
unwrapped = None
if ip_int >> 32 == 0x0064ff9b0000000000000000: # NAT64 64:ff9b::/96
unwrapped = ipaddress.IPv4Address(ip_int & 0xFFFFFFFF)
elif ip_int < 2**32 and ip_int not in (0, 1): # IPv4-compatible ::w.x.y.z
unwrapped = ipaddress.IPv4Address(ip_int)
else:
isatap_id = (ip_int >> 32) & 0xFFFFFFFF
if isatap_id in (0x00005efe, 0x02005efe): # ISATAP tunnel
unwrapped = ipaddress.IPv4Address(ip_int & 0xFFFFFFFF)

if unwrapped is not None:
is_blocked = not unwrapped.is_global or unwrapped.is_multicast

if is_blocked:
# πŸ›‘οΈ Sentinel: Sanitize log input using repr() to prevent CRLF/Log Injection
Expand Down
Loading