Coverage for src/local_deep_research/settings/env_definitions/security.py: 100%
4 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-03 23:15 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-03 23:15 +0000
1"""
2Security environment settings.
4These settings control security-related behavior like SSRF validation
5and CORS origin restrictions.
6"""
8import os
9from ..env_settings import BooleanSetting, StringSetting
12# External environment variables (set by pytest, CI systems)
13# These are read directly since we don't control them
14PYTEST_CURRENT_TEST = os.environ.get("PYTEST_CURRENT_TEST")
17# LDR Security settings (our application's security configuration)
18SECURITY_SETTINGS = [
19 StringSetting(
20 key="security.cors.allowed_origins",
21 description=(
22 "Allowed CORS origins for API routes (comma-separated). "
23 "Use '*' for all origins, empty for same-origin only. "
24 "Example: 'https://example.com,https://app.example.com'"
25 ),
26 default=None,
27 ),
28 StringSetting(
29 key="security.websocket.allowed_origins",
30 description=(
31 "Allowed origins for WebSocket/Socket.IO connections (comma-separated). "
32 "Use '*' for all origins (default), empty for same-origin only. "
33 "Example: 'https://example.com,https://app.example.com'"
34 ),
35 default=None,
36 ),
37 BooleanSetting(
38 key="notifications.allow_private_ips",
39 description=(
40 "Allow notification webhooks to target private/local IP addresses. "
41 "Environment-only to prevent SSRF bypass via the user-writable settings API. "
42 "Only enable this if your notification endpoints are on a trusted local network."
43 ),
44 default=False,
45 ),
46 BooleanSetting(
47 key="security.allow_nat64",
48 description=(
49 "Allow outbound traffic to NAT64 prefixes (64:ff9b::/96 RFC 6052 "
50 "well-known and 64:ff9b:1::/48 RFC 8215 local-use). Disabled by "
51 "default to close the IPv6-wrapped SSRF bypass class — on hosts "
52 "configured with NAT64 routes, attacker-supplied URLs can wrap "
53 "cloud-metadata or RFC1918 destinations through these prefixes. "
54 "Enable only on IPv6-only deployments (DNS64+NAT64) where "
55 "outbound IPv4 traffic is synthesized through this prefix and "
56 "the operator has accepted the residual SSRF risk. 6to4 "
57 "(2002::/16), Teredo (2001::/32), and the discard prefix "
58 "(100::/64) remain unconditionally blocked because they have no "
59 "live legitimate use in 2026. The cloud-metadata block "
60 "(ALWAYS_BLOCKED_METADATA_IPS) still applies via embedded-IPv4 "
61 "extraction — see SECURITY.md."
62 ),
63 default=False,
64 ),
65 BooleanSetting(
66 key="notifications.allow_outbound",
67 description=(
68 "Master switch for outbound notification webhooks (Apprise). "
69 "Disabled by default because Apprise re-resolves DNS at send time, "
70 "leaving a DNS-rebinding TOCTOU window that cannot be closed in code "
71 "(Apprise exposes no Session/DNS hook). See SECURITY.md "
72 "'Notification Webhook SSRF' for details. Set to true only after "
73 "reviewing the residual risk. Distinct from the per-user "
74 "notifications.enabled toggle in the settings UI: this is the "
75 "server-level operator gate, env-only so it cannot be flipped via "
76 "the user-writable settings API."
77 ),
78 default=False,
79 ),
80]