Files
TREK/wiki/Internal-Network-Access.md
T
Julien G. 6072b969d6 Bug fixes - May 2nd 2026 (#941)
* fix: collab chat input hidden by mobile bottom nav bar

Closes #939

* chore: prepare database for nest + typeorm

* fix(ssrf): relax internal network resolution (#947)

* docs(ssrf): update Internal-Network-Access wiki to reflect relaxed guard

Loopback, link-local, and .local/.internal hostnames are now all
overridable with ALLOW_INTERNAL_NETWORK=true (commit 9a08368). Merge
the two-tier "always blocked / conditionally blocked" structure into a
single table, add a warning about cloud metadata exposure.

* fix(ssrf): let .local/.internal hostnames pass to IP-level checks

The pre-DNS hostname block was redundant: any .local/.internal host
that resolves to a private IP is already gated by isPrivateNetwork +
ALLOW_INTERNAL_NETWORK, and any that resolves to loopback/link-local
is caught by isAlwaysBlocked unconditionally.

Dropping the hostname pre-check means Docker/LAN deployments can reach
services on .local hostnames (e.g. immich.local) with
ALLOW_INTERNAL_NETWORK=true, while loopback and link-local IPs
(including 169.254.169.254) remain hard-blocked with no override.

Reverts the isAlwaysBlocked guard loosening from 9a08368.

* fix(auth): trim username and email on all write paths

Self-registration stored values verbatim, so trailing whitespace could
produce rows that lookup code (which trims input) silently misses.
Trim username and email before validation and INSERT in registerUser,
adminService.updateUser, and oidcService.findOrCreateUser. updateSettings
and adminService.createUser already trimmed correctly.

Adds a one-shot backfill migration (trimUserWhitespace) that trims
existing dirty rows; collisions are resolved by appending __migrated_<id>
to the value with a loud console.warn so operators can review affected
accounts.

18 new tests covering registration trim, duplicate detection, admin
update trim, trip-member lookup regression, and all migration branches.

* feat(notices): add v3014-whitespace-collision admin notice

Adds a dismissible banner for admins on v3.0.14+ that fires only when
the whitespace-trimming migration detected a username/email collision
(stored in app_settings as whitespace_migration_collision=true).

Notice conditions: existingUserBeforeVersion(3.0.14) + role=admin +
custom predicate reading the app_settings flag. Predicate registered in
registry.ts; migration step writes the flag when hadCollision=true.

All 15 translation files updated with title/body keys.
7 integration tests added (SN-COLLISION-1 through -7) covering all
condition branches: shown when all conditions met, hidden when flag
absent/false, hidden for non-admin, hidden for new user, hidden below
min app version, hidden after dismissal.
2026-05-03 17:39:45 +02:00

3.0 KiB

Internal Network Access

TREK makes outbound HTTP requests when you configure integrations such as Immich or Synology Photos. By default, it blocks requests to private and local IP ranges to prevent server-side request forgery (SSRF) attacks. You need to allow internal network access when those services are hosted on your LAN.

Default behavior

All outbound requests go through an SSRF guard (ssrfGuard.ts). The guard resolves the hostname to an IP address before allowing the connection and blocks addresses in private ranges.

Always blocked (no override possible)

These ranges are blocked regardless of any setting:

Range Description
127.0.0.0/8, ::1 Loopback
0.0.0.0/8 Unspecified
169.254.0.0/16, fe80::/10 Link-local / cloud metadata endpoints
::ffff:127.x.x.x, ::ffff:169.254.x.x IPv4-mapped loopback and link-local

Blocked unless ALLOW_INTERNAL_NETWORK=true

Range / Hostname Description
10.0.0.0/8 RFC-1918 private
172.16.0.0/12 RFC-1918 private
192.168.0.0/16 RFC-1918 private
100.64.0.0/10 CGNAT / Tailscale shared address space
fc00::/7 IPv6 ULA
IPv4-mapped RFC-1918 variants e.g. ::ffff:10.x, ::ffff:192.168.x
*.local, *.internal hostnames mDNS / internal DNS suffixes (e.g. Docker service names, LAN hosts)

The hostname localhost is not blocked at the hostname stage, but it resolves to 127.0.0.1 which is caught by the loopback rule above and is therefore always blocked.

*.local and *.internal hostnames are permitted when ALLOW_INTERNAL_NETWORK=true — the guard still resolves them to an IP and enforces all IP-level rules, so any such hostname that resolves to a loopback or link-local address remains blocked regardless.

When to enable

Set ALLOW_INTERNAL_NETWORK=true when Immich, Synology Photos, or another integrated service is hosted on your local network and you need TREK to reach it.

See Environment-Variables for how to set environment variables.

Admin: Set ALLOW_INTERNAL_NETWORK=true in Environment-Variables before configuring Immich or Synology on a LAN.

DNS rebinding protection

Even with ALLOW_INTERNAL_NETWORK=true, TREK pins the DNS resolution to prevent rebinding attacks. When the guard checks a URL, it resolves the hostname once and records the IP. The outbound connection is then made directly to that IP using a pinned dispatcher (via undici), so the hostname cannot re-resolve to a different address between the check and the actual request.

Audit log

When a user saves an Immich URL that resolves to a private IP, TREK records an immich.private_ip_configured entry in the Audit-Log including the URL and the resolved IP address. This audit event is specific to Immich; Synology Photos does not emit an equivalent event.

See also